diff options
author | Trygve Laugstøl <trygvis@inamo.no> | 2018-08-23 17:08:59 +0200 |
---|---|---|
committer | Trygve Laugstøl <trygvis@inamo.no> | 2018-08-23 17:12:21 +0200 |
commit | 3061ecca3d0fdfb87dabbf5f63c9e06c2a30f53a (patch) | |
tree | ab49cc16ed0b853452c5c2ed2d3042416d628986 /thirdparty/nRF5_SDK_15.0.0_a53641a/components/ble/common | |
download | iot-sensors-master.tar.gz iot-sensors-master.tar.bz2 iot-sensors-master.tar.xz iot-sensors-master.zip |
Diffstat (limited to 'thirdparty/nRF5_SDK_15.0.0_a53641a/components/ble/common')
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(¢ral_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(¢ral_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__ + +/** @} */ |