aboutsummaryrefslogtreecommitdiff
path: root/thirdparty/nRF5_SDK_15.0.0_a53641a/components/ble/common
diff options
context:
space:
mode:
Diffstat (limited to 'thirdparty/nRF5_SDK_15.0.0_a53641a/components/ble/common')
-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
11 files changed, 3634 insertions, 0 deletions
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__
+
+/** @} */