diff options
Diffstat (limited to 'thirdparty/nRF5_SDK_15.0.0_a53641a/components/ble/ble_services/ble_escs')
3 files changed, 1067 insertions, 0 deletions
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__ |