Nordic stack and drivers for the mbed BLE API

Dependents:   BLE_ANCS_SDAPI BLE_temperature BLE_HeartRate writable_gatt ... more

Committer:
Vincent Coubard
Date:
Wed Sep 14 14:39:43 2016 +0100
Revision:
638:c90ae1400bf2
Sync with bdab10dc0f90748b6989c8b577771bb403ca6bd8 from ARMmbed/mbed-os.

Who changed what in which revision?

UserRevisionLine numberNew contents of line
Vincent Coubard 638:c90ae1400bf2 1 /*
Vincent Coubard 638:c90ae1400bf2 2 * Copyright (c) Nordic Semiconductor ASA
Vincent Coubard 638:c90ae1400bf2 3 * All rights reserved.
Vincent Coubard 638:c90ae1400bf2 4 *
Vincent Coubard 638:c90ae1400bf2 5 * Redistribution and use in source and binary forms, with or without modification,
Vincent Coubard 638:c90ae1400bf2 6 * are permitted provided that the following conditions are met:
Vincent Coubard 638:c90ae1400bf2 7 *
Vincent Coubard 638:c90ae1400bf2 8 * 1. Redistributions of source code must retain the above copyright notice, this
Vincent Coubard 638:c90ae1400bf2 9 * list of conditions and the following disclaimer.
Vincent Coubard 638:c90ae1400bf2 10 *
Vincent Coubard 638:c90ae1400bf2 11 * 2. Redistributions in binary form must reproduce the above copyright notice, this
Vincent Coubard 638:c90ae1400bf2 12 * list of conditions and the following disclaimer in the documentation and/or
Vincent Coubard 638:c90ae1400bf2 13 * other materials provided with the distribution.
Vincent Coubard 638:c90ae1400bf2 14 *
Vincent Coubard 638:c90ae1400bf2 15 * 3. Neither the name of Nordic Semiconductor ASA nor the names of other
Vincent Coubard 638:c90ae1400bf2 16 * contributors to this software may be used to endorse or promote products
Vincent Coubard 638:c90ae1400bf2 17 * derived from this software without specific prior written permission.
Vincent Coubard 638:c90ae1400bf2 18 *
Vincent Coubard 638:c90ae1400bf2 19 *
Vincent Coubard 638:c90ae1400bf2 20 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
Vincent Coubard 638:c90ae1400bf2 21 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
Vincent Coubard 638:c90ae1400bf2 22 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
Vincent Coubard 638:c90ae1400bf2 23 * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR
Vincent Coubard 638:c90ae1400bf2 24 * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
Vincent Coubard 638:c90ae1400bf2 25 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
Vincent Coubard 638:c90ae1400bf2 26 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
Vincent Coubard 638:c90ae1400bf2 27 * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
Vincent Coubard 638:c90ae1400bf2 28 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
Vincent Coubard 638:c90ae1400bf2 29 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
Vincent Coubard 638:c90ae1400bf2 30 *
Vincent Coubard 638:c90ae1400bf2 31 */
Vincent Coubard 638:c90ae1400bf2 32
Vincent Coubard 638:c90ae1400bf2 33 #include "ble_advdata.h"
Vincent Coubard 638:c90ae1400bf2 34 #include "nordic_common.h"
Vincent Coubard 638:c90ae1400bf2 35 #include "nrf_error.h"
Vincent Coubard 638:c90ae1400bf2 36 #include "ble_gap.h"
Vincent Coubard 638:c90ae1400bf2 37 #include "ble_srv_common.h"
Vincent Coubard 638:c90ae1400bf2 38 #include "app_util.h"
Vincent Coubard 638:c90ae1400bf2 39
Vincent Coubard 638:c90ae1400bf2 40 // NOTE: For now, Security Manager Out of Band Flags (OOB) are omitted from the advertising data.
Vincent Coubard 638:c90ae1400bf2 41
Vincent Coubard 638:c90ae1400bf2 42 // Types of LE Bluetooth Device Address AD type
Vincent Coubard 638:c90ae1400bf2 43 #define AD_TYPE_BLE_DEVICE_ADDR_TYPE_PUBLIC 0UL
Vincent Coubard 638:c90ae1400bf2 44 #define AD_TYPE_BLE_DEVICE_ADDR_TYPE_RANDOM 1UL
Vincent Coubard 638:c90ae1400bf2 45
Vincent Coubard 638:c90ae1400bf2 46 static uint32_t tk_value_encode(ble_advdata_tk_value_t * p_tk_value,
Vincent Coubard 638:c90ae1400bf2 47 uint8_t * p_encoded_data,
Vincent Coubard 638:c90ae1400bf2 48 uint16_t * p_offset,
Vincent Coubard 638:c90ae1400bf2 49 uint16_t max_size)
Vincent Coubard 638:c90ae1400bf2 50 {
Vincent Coubard 638:c90ae1400bf2 51 int8_t i;
Vincent Coubard 638:c90ae1400bf2 52
Vincent Coubard 638:c90ae1400bf2 53 // Check for buffer overflow.
Vincent Coubard 638:c90ae1400bf2 54 if (((*p_offset) + AD_TYPE_TK_VALUE_SIZE) > max_size)
Vincent Coubard 638:c90ae1400bf2 55 {
Vincent Coubard 638:c90ae1400bf2 56 return NRF_ERROR_DATA_SIZE;
Vincent Coubard 638:c90ae1400bf2 57 }
Vincent Coubard 638:c90ae1400bf2 58
Vincent Coubard 638:c90ae1400bf2 59 // Encode LE Role.
Vincent Coubard 638:c90ae1400bf2 60 p_encoded_data[*p_offset] = (uint8_t)(ADV_AD_TYPE_FIELD_SIZE + AD_TYPE_TK_VALUE_DATA_SIZE);
Vincent Coubard 638:c90ae1400bf2 61 *p_offset += ADV_LENGTH_FIELD_SIZE;
Vincent Coubard 638:c90ae1400bf2 62 p_encoded_data[*p_offset] = BLE_GAP_AD_TYPE_SECURITY_MANAGER_TK_VALUE;
Vincent Coubard 638:c90ae1400bf2 63 *p_offset += ADV_AD_TYPE_FIELD_SIZE;
Vincent Coubard 638:c90ae1400bf2 64
Vincent Coubard 638:c90ae1400bf2 65 for (i = AD_TYPE_TK_VALUE_DATA_SIZE - 1; i >= 0; i--, (*p_offset)++)
Vincent Coubard 638:c90ae1400bf2 66 {
Vincent Coubard 638:c90ae1400bf2 67 p_encoded_data[*p_offset] = p_tk_value->tk[i];
Vincent Coubard 638:c90ae1400bf2 68 }
Vincent Coubard 638:c90ae1400bf2 69
Vincent Coubard 638:c90ae1400bf2 70 return NRF_SUCCESS;
Vincent Coubard 638:c90ae1400bf2 71 }
Vincent Coubard 638:c90ae1400bf2 72
Vincent Coubard 638:c90ae1400bf2 73 static uint32_t le_role_encode(ble_advdata_le_role_t le_role,
Vincent Coubard 638:c90ae1400bf2 74 uint8_t * p_encoded_data,
Vincent Coubard 638:c90ae1400bf2 75 uint16_t * p_offset,
Vincent Coubard 638:c90ae1400bf2 76 uint16_t max_size)
Vincent Coubard 638:c90ae1400bf2 77 {
Vincent Coubard 638:c90ae1400bf2 78 // Check for buffer overflow.
Vincent Coubard 638:c90ae1400bf2 79 if (((*p_offset) + AD_TYPE_LE_ROLE_SIZE) > max_size)
Vincent Coubard 638:c90ae1400bf2 80 {
Vincent Coubard 638:c90ae1400bf2 81 return NRF_ERROR_DATA_SIZE;
Vincent Coubard 638:c90ae1400bf2 82 }
Vincent Coubard 638:c90ae1400bf2 83
Vincent Coubard 638:c90ae1400bf2 84 // Encode LE Role.
Vincent Coubard 638:c90ae1400bf2 85 p_encoded_data[*p_offset] = (uint8_t)(ADV_AD_TYPE_FIELD_SIZE + AD_TYPE_LE_ROLE_DATA_SIZE);
Vincent Coubard 638:c90ae1400bf2 86 *p_offset += ADV_LENGTH_FIELD_SIZE;
Vincent Coubard 638:c90ae1400bf2 87 p_encoded_data[*p_offset] = BLE_GAP_AD_TYPE_LE_ROLE;
Vincent Coubard 638:c90ae1400bf2 88 *p_offset += ADV_AD_TYPE_FIELD_SIZE;
Vincent Coubard 638:c90ae1400bf2 89 switch(le_role)
Vincent Coubard 638:c90ae1400bf2 90 {
Vincent Coubard 638:c90ae1400bf2 91 case BLE_ADVDATA_ROLE_ONLY_PERIPH:
Vincent Coubard 638:c90ae1400bf2 92 p_encoded_data[*p_offset] = 0;
Vincent Coubard 638:c90ae1400bf2 93 break;
Vincent Coubard 638:c90ae1400bf2 94 case BLE_ADVDATA_ROLE_ONLY_CENTRAL:
Vincent Coubard 638:c90ae1400bf2 95 p_encoded_data[*p_offset] = 1;
Vincent Coubard 638:c90ae1400bf2 96 break;
Vincent Coubard 638:c90ae1400bf2 97 case BLE_ADVDATA_ROLE_BOTH_PERIPH_PREFERRED:
Vincent Coubard 638:c90ae1400bf2 98 p_encoded_data[*p_offset] = 2;
Vincent Coubard 638:c90ae1400bf2 99 break;
Vincent Coubard 638:c90ae1400bf2 100 case BLE_ADVDATA_ROLE_BOTH_CENTRAL_PREFERRED:
Vincent Coubard 638:c90ae1400bf2 101 p_encoded_data[*p_offset] = 3;
Vincent Coubard 638:c90ae1400bf2 102 break;
Vincent Coubard 638:c90ae1400bf2 103 default:
Vincent Coubard 638:c90ae1400bf2 104 return NRF_ERROR_INVALID_PARAM;
Vincent Coubard 638:c90ae1400bf2 105 }
Vincent Coubard 638:c90ae1400bf2 106 *p_offset += AD_TYPE_LE_ROLE_DATA_SIZE;
Vincent Coubard 638:c90ae1400bf2 107
Vincent Coubard 638:c90ae1400bf2 108 return NRF_SUCCESS;
Vincent Coubard 638:c90ae1400bf2 109 }
Vincent Coubard 638:c90ae1400bf2 110
Vincent Coubard 638:c90ae1400bf2 111 static uint32_t ble_device_addr_encode(uint8_t * p_encoded_data,
Vincent Coubard 638:c90ae1400bf2 112 uint16_t * p_offset,
Vincent Coubard 638:c90ae1400bf2 113 uint16_t max_size)
Vincent Coubard 638:c90ae1400bf2 114 {
Vincent Coubard 638:c90ae1400bf2 115 uint32_t err_code;
Vincent Coubard 638:c90ae1400bf2 116 ble_gap_addr_t device_addr;
Vincent Coubard 638:c90ae1400bf2 117
Vincent Coubard 638:c90ae1400bf2 118 // Check for buffer overflow.
Vincent Coubard 638:c90ae1400bf2 119 if (((*p_offset) + AD_TYPE_BLE_DEVICE_ADDR_SIZE) > max_size)
Vincent Coubard 638:c90ae1400bf2 120 {
Vincent Coubard 638:c90ae1400bf2 121 return NRF_ERROR_DATA_SIZE;
Vincent Coubard 638:c90ae1400bf2 122 }
Vincent Coubard 638:c90ae1400bf2 123
Vincent Coubard 638:c90ae1400bf2 124 // Get BLE address
Vincent Coubard 638:c90ae1400bf2 125 err_code = sd_ble_gap_address_get(&device_addr);
Vincent Coubard 638:c90ae1400bf2 126 if (err_code != NRF_SUCCESS)
Vincent Coubard 638:c90ae1400bf2 127 {
Vincent Coubard 638:c90ae1400bf2 128 return err_code;
Vincent Coubard 638:c90ae1400bf2 129 }
Vincent Coubard 638:c90ae1400bf2 130
Vincent Coubard 638:c90ae1400bf2 131 // Encode LE Bluetooth Device Address
Vincent Coubard 638:c90ae1400bf2 132 p_encoded_data[*p_offset] = (uint8_t)(ADV_AD_TYPE_FIELD_SIZE +
Vincent Coubard 638:c90ae1400bf2 133 AD_TYPE_BLE_DEVICE_ADDR_DATA_SIZE);
Vincent Coubard 638:c90ae1400bf2 134 *p_offset += ADV_LENGTH_FIELD_SIZE;
Vincent Coubard 638:c90ae1400bf2 135 p_encoded_data[*p_offset] = BLE_GAP_AD_TYPE_LE_BLUETOOTH_DEVICE_ADDRESS;
Vincent Coubard 638:c90ae1400bf2 136 *p_offset += ADV_AD_TYPE_FIELD_SIZE;
Vincent Coubard 638:c90ae1400bf2 137 memcpy(&p_encoded_data[*p_offset], &device_addr.addr[0], BLE_GAP_ADDR_LEN);
Vincent Coubard 638:c90ae1400bf2 138 *p_offset += BLE_GAP_ADDR_LEN;
Vincent Coubard 638:c90ae1400bf2 139 if(BLE_GAP_ADDR_TYPE_PUBLIC == device_addr.addr_type)
Vincent Coubard 638:c90ae1400bf2 140 {
Vincent Coubard 638:c90ae1400bf2 141 p_encoded_data[*p_offset] = AD_TYPE_BLE_DEVICE_ADDR_TYPE_PUBLIC;
Vincent Coubard 638:c90ae1400bf2 142 }
Vincent Coubard 638:c90ae1400bf2 143 else
Vincent Coubard 638:c90ae1400bf2 144 {
Vincent Coubard 638:c90ae1400bf2 145 p_encoded_data[*p_offset] = AD_TYPE_BLE_DEVICE_ADDR_TYPE_RANDOM;
Vincent Coubard 638:c90ae1400bf2 146 }
Vincent Coubard 638:c90ae1400bf2 147 *p_offset += AD_TYPE_BLE_DEVICE_ADDR_TYPE_SIZE;
Vincent Coubard 638:c90ae1400bf2 148
Vincent Coubard 638:c90ae1400bf2 149 return NRF_SUCCESS;
Vincent Coubard 638:c90ae1400bf2 150 }
Vincent Coubard 638:c90ae1400bf2 151
Vincent Coubard 638:c90ae1400bf2 152 static uint32_t name_encode(const ble_advdata_t * p_advdata,
Vincent Coubard 638:c90ae1400bf2 153 uint8_t * p_encoded_data,
Vincent Coubard 638:c90ae1400bf2 154 uint16_t * p_offset,
Vincent Coubard 638:c90ae1400bf2 155 uint16_t max_size)
Vincent Coubard 638:c90ae1400bf2 156 {
Vincent Coubard 638:c90ae1400bf2 157 uint32_t err_code;
Vincent Coubard 638:c90ae1400bf2 158 uint16_t rem_adv_data_len;
Vincent Coubard 638:c90ae1400bf2 159 uint16_t actual_length;
Vincent Coubard 638:c90ae1400bf2 160 uint8_t adv_data_format;
Vincent Coubard 638:c90ae1400bf2 161
Vincent Coubard 638:c90ae1400bf2 162
Vincent Coubard 638:c90ae1400bf2 163 // Validate parameters
Vincent Coubard 638:c90ae1400bf2 164 if((BLE_ADVDATA_SHORT_NAME == p_advdata->name_type) && (0 == p_advdata->short_name_len))
Vincent Coubard 638:c90ae1400bf2 165 {
Vincent Coubard 638:c90ae1400bf2 166 return NRF_ERROR_INVALID_PARAM;
Vincent Coubard 638:c90ae1400bf2 167 }
Vincent Coubard 638:c90ae1400bf2 168
Vincent Coubard 638:c90ae1400bf2 169 // Check for buffer overflow.
Vincent Coubard 638:c90ae1400bf2 170 if ( (((*p_offset) + ADV_AD_DATA_OFFSET) > max_size) ||
Vincent Coubard 638:c90ae1400bf2 171 ( (BLE_ADVDATA_SHORT_NAME == p_advdata->name_type) &&
Vincent Coubard 638:c90ae1400bf2 172 (((*p_offset) + ADV_AD_DATA_OFFSET + p_advdata->short_name_len) > max_size)))
Vincent Coubard 638:c90ae1400bf2 173 {
Vincent Coubard 638:c90ae1400bf2 174 return NRF_ERROR_DATA_SIZE;
Vincent Coubard 638:c90ae1400bf2 175 }
Vincent Coubard 638:c90ae1400bf2 176
Vincent Coubard 638:c90ae1400bf2 177 rem_adv_data_len = max_size - (*p_offset) - ADV_AD_DATA_OFFSET;
Vincent Coubard 638:c90ae1400bf2 178 actual_length = rem_adv_data_len;
Vincent Coubard 638:c90ae1400bf2 179
Vincent Coubard 638:c90ae1400bf2 180 // Get GAP device name and length
Vincent Coubard 638:c90ae1400bf2 181 err_code = sd_ble_gap_device_name_get(&p_encoded_data[(*p_offset) + ADV_AD_DATA_OFFSET],
Vincent Coubard 638:c90ae1400bf2 182 &actual_length);
Vincent Coubard 638:c90ae1400bf2 183 if (err_code != NRF_SUCCESS)
Vincent Coubard 638:c90ae1400bf2 184 {
Vincent Coubard 638:c90ae1400bf2 185 return err_code;
Vincent Coubard 638:c90ae1400bf2 186 }
Vincent Coubard 638:c90ae1400bf2 187
Vincent Coubard 638:c90ae1400bf2 188 // Check if device intend to use short name and it can fit available data size.
Vincent Coubard 638:c90ae1400bf2 189 if ((p_advdata->name_type == BLE_ADVDATA_FULL_NAME) && (actual_length <= rem_adv_data_len))
Vincent Coubard 638:c90ae1400bf2 190 {
Vincent Coubard 638:c90ae1400bf2 191 // Complete device name can fit, setting Complete Name in Adv Data.
Vincent Coubard 638:c90ae1400bf2 192 adv_data_format = BLE_GAP_AD_TYPE_COMPLETE_LOCAL_NAME;
Vincent Coubard 638:c90ae1400bf2 193 }
Vincent Coubard 638:c90ae1400bf2 194 else
Vincent Coubard 638:c90ae1400bf2 195 {
Vincent Coubard 638:c90ae1400bf2 196 // Else short name needs to be used. Or application has requested use of short name.
Vincent Coubard 638:c90ae1400bf2 197 adv_data_format = BLE_GAP_AD_TYPE_SHORT_LOCAL_NAME;
Vincent Coubard 638:c90ae1400bf2 198
Vincent Coubard 638:c90ae1400bf2 199 // If application has set a preference on the short name size, it needs to be considered,
Vincent Coubard 638:c90ae1400bf2 200 // else fit what can be fit.
Vincent Coubard 638:c90ae1400bf2 201 if ((BLE_ADVDATA_SHORT_NAME == p_advdata->name_type) &&
Vincent Coubard 638:c90ae1400bf2 202 (p_advdata->short_name_len <= rem_adv_data_len))
Vincent Coubard 638:c90ae1400bf2 203 {
Vincent Coubard 638:c90ae1400bf2 204 // Short name fits available size.
Vincent Coubard 638:c90ae1400bf2 205 actual_length = p_advdata->short_name_len;
Vincent Coubard 638:c90ae1400bf2 206 }
Vincent Coubard 638:c90ae1400bf2 207 // Else whatever can fit the data buffer will be packed.
Vincent Coubard 638:c90ae1400bf2 208 else
Vincent Coubard 638:c90ae1400bf2 209 {
Vincent Coubard 638:c90ae1400bf2 210 actual_length = rem_adv_data_len;
Vincent Coubard 638:c90ae1400bf2 211 }
Vincent Coubard 638:c90ae1400bf2 212 }
Vincent Coubard 638:c90ae1400bf2 213
Vincent Coubard 638:c90ae1400bf2 214 // There is only 1 byte intended to encode length which is (actual_length + ADV_AD_TYPE_FIELD_SIZE)
Vincent Coubard 638:c90ae1400bf2 215 if(actual_length > (0x00FF - ADV_AD_TYPE_FIELD_SIZE))
Vincent Coubard 638:c90ae1400bf2 216 {
Vincent Coubard 638:c90ae1400bf2 217 return NRF_ERROR_DATA_SIZE;
Vincent Coubard 638:c90ae1400bf2 218 }
Vincent Coubard 638:c90ae1400bf2 219
Vincent Coubard 638:c90ae1400bf2 220 // Complete name field in encoded data.
Vincent Coubard 638:c90ae1400bf2 221 p_encoded_data[*p_offset] = (uint8_t)(ADV_AD_TYPE_FIELD_SIZE + actual_length);
Vincent Coubard 638:c90ae1400bf2 222 *p_offset += ADV_LENGTH_FIELD_SIZE;
Vincent Coubard 638:c90ae1400bf2 223 p_encoded_data[*p_offset] = adv_data_format;
Vincent Coubard 638:c90ae1400bf2 224 *p_offset += ADV_AD_TYPE_FIELD_SIZE;
Vincent Coubard 638:c90ae1400bf2 225 *p_offset += actual_length;
Vincent Coubard 638:c90ae1400bf2 226
Vincent Coubard 638:c90ae1400bf2 227 return NRF_SUCCESS;
Vincent Coubard 638:c90ae1400bf2 228 }
Vincent Coubard 638:c90ae1400bf2 229
Vincent Coubard 638:c90ae1400bf2 230
Vincent Coubard 638:c90ae1400bf2 231 static uint32_t appearance_encode(uint8_t * p_encoded_data,
Vincent Coubard 638:c90ae1400bf2 232 uint16_t * p_offset,
Vincent Coubard 638:c90ae1400bf2 233 uint16_t max_size)
Vincent Coubard 638:c90ae1400bf2 234 {
Vincent Coubard 638:c90ae1400bf2 235 uint32_t err_code;
Vincent Coubard 638:c90ae1400bf2 236 uint16_t appearance;
Vincent Coubard 638:c90ae1400bf2 237
Vincent Coubard 638:c90ae1400bf2 238 // Check for buffer overflow.
Vincent Coubard 638:c90ae1400bf2 239 if (((*p_offset) + AD_TYPE_APPEARANCE_SIZE) > max_size)
Vincent Coubard 638:c90ae1400bf2 240 {
Vincent Coubard 638:c90ae1400bf2 241 return NRF_ERROR_DATA_SIZE;
Vincent Coubard 638:c90ae1400bf2 242 }
Vincent Coubard 638:c90ae1400bf2 243
Vincent Coubard 638:c90ae1400bf2 244 // Get GAP appearance field.
Vincent Coubard 638:c90ae1400bf2 245 err_code = sd_ble_gap_appearance_get(&appearance);
Vincent Coubard 638:c90ae1400bf2 246 if (err_code != NRF_SUCCESS)
Vincent Coubard 638:c90ae1400bf2 247 {
Vincent Coubard 638:c90ae1400bf2 248 return err_code;
Vincent Coubard 638:c90ae1400bf2 249 }
Vincent Coubard 638:c90ae1400bf2 250
Vincent Coubard 638:c90ae1400bf2 251 // Encode Length, AD Type and Appearance.
Vincent Coubard 638:c90ae1400bf2 252 p_encoded_data[*p_offset] = (uint8_t)(ADV_AD_TYPE_FIELD_SIZE + AD_TYPE_APPEARANCE_DATA_SIZE);
Vincent Coubard 638:c90ae1400bf2 253 *p_offset += ADV_LENGTH_FIELD_SIZE;
Vincent Coubard 638:c90ae1400bf2 254 p_encoded_data[*p_offset] = BLE_GAP_AD_TYPE_APPEARANCE;
Vincent Coubard 638:c90ae1400bf2 255 *p_offset += ADV_AD_TYPE_FIELD_SIZE;
Vincent Coubard 638:c90ae1400bf2 256 *p_offset += uint16_encode(appearance, &p_encoded_data[*p_offset]);
Vincent Coubard 638:c90ae1400bf2 257
Vincent Coubard 638:c90ae1400bf2 258 return NRF_SUCCESS;
Vincent Coubard 638:c90ae1400bf2 259 }
Vincent Coubard 638:c90ae1400bf2 260
Vincent Coubard 638:c90ae1400bf2 261 static uint32_t flags_encode(int8_t flags,
Vincent Coubard 638:c90ae1400bf2 262 uint8_t * p_encoded_data,
Vincent Coubard 638:c90ae1400bf2 263 uint16_t * p_offset,
Vincent Coubard 638:c90ae1400bf2 264 uint16_t max_size)
Vincent Coubard 638:c90ae1400bf2 265 {
Vincent Coubard 638:c90ae1400bf2 266 // Check for buffer overflow.
Vincent Coubard 638:c90ae1400bf2 267 if (((*p_offset) + AD_TYPE_FLAGS_SIZE) > max_size)
Vincent Coubard 638:c90ae1400bf2 268 {
Vincent Coubard 638:c90ae1400bf2 269 return NRF_ERROR_DATA_SIZE;
Vincent Coubard 638:c90ae1400bf2 270 }
Vincent Coubard 638:c90ae1400bf2 271
Vincent Coubard 638:c90ae1400bf2 272 // Encode flags.
Vincent Coubard 638:c90ae1400bf2 273 p_encoded_data[*p_offset] = (uint8_t)(ADV_AD_TYPE_FIELD_SIZE + AD_TYPE_FLAGS_DATA_SIZE);
Vincent Coubard 638:c90ae1400bf2 274 *p_offset += ADV_LENGTH_FIELD_SIZE;
Vincent Coubard 638:c90ae1400bf2 275 p_encoded_data[*p_offset] = BLE_GAP_AD_TYPE_FLAGS;
Vincent Coubard 638:c90ae1400bf2 276 *p_offset += ADV_AD_TYPE_FIELD_SIZE;
Vincent Coubard 638:c90ae1400bf2 277 p_encoded_data[*p_offset] = flags;
Vincent Coubard 638:c90ae1400bf2 278 *p_offset += AD_TYPE_FLAGS_DATA_SIZE;
Vincent Coubard 638:c90ae1400bf2 279
Vincent Coubard 638:c90ae1400bf2 280 return NRF_SUCCESS;
Vincent Coubard 638:c90ae1400bf2 281 }
Vincent Coubard 638:c90ae1400bf2 282
Vincent Coubard 638:c90ae1400bf2 283 static uint32_t sec_mgr_oob_flags_encode(uint8_t oob_flags,
Vincent Coubard 638:c90ae1400bf2 284 uint8_t * p_encoded_data,
Vincent Coubard 638:c90ae1400bf2 285 uint16_t * p_offset,
Vincent Coubard 638:c90ae1400bf2 286 uint16_t max_size)
Vincent Coubard 638:c90ae1400bf2 287 {
Vincent Coubard 638:c90ae1400bf2 288 // Check for buffer overflow.
Vincent Coubard 638:c90ae1400bf2 289 if (((*p_offset) + AD_TYPE_OOB_FLAGS_SIZE) > max_size)
Vincent Coubard 638:c90ae1400bf2 290 {
Vincent Coubard 638:c90ae1400bf2 291 return NRF_ERROR_DATA_SIZE;
Vincent Coubard 638:c90ae1400bf2 292 }
Vincent Coubard 638:c90ae1400bf2 293
Vincent Coubard 638:c90ae1400bf2 294 // Encode flags.
Vincent Coubard 638:c90ae1400bf2 295 p_encoded_data[*p_offset] = (uint8_t)(ADV_AD_TYPE_FIELD_SIZE + AD_TYPE_OOB_FLAGS_DATA_SIZE);
Vincent Coubard 638:c90ae1400bf2 296 *p_offset += ADV_LENGTH_FIELD_SIZE;
Vincent Coubard 638:c90ae1400bf2 297 p_encoded_data[*p_offset] = BLE_GAP_AD_TYPE_SECURITY_MANAGER_OOB_FLAGS;
Vincent Coubard 638:c90ae1400bf2 298 *p_offset += ADV_AD_TYPE_FIELD_SIZE;
Vincent Coubard 638:c90ae1400bf2 299 p_encoded_data[*p_offset] = oob_flags;
Vincent Coubard 638:c90ae1400bf2 300 *p_offset += AD_TYPE_OOB_FLAGS_DATA_SIZE;
Vincent Coubard 638:c90ae1400bf2 301
Vincent Coubard 638:c90ae1400bf2 302 return NRF_SUCCESS;
Vincent Coubard 638:c90ae1400bf2 303 }
Vincent Coubard 638:c90ae1400bf2 304
Vincent Coubard 638:c90ae1400bf2 305 static uint32_t tx_power_level_encode(int8_t tx_power_level,
Vincent Coubard 638:c90ae1400bf2 306 uint8_t * p_encoded_data,
Vincent Coubard 638:c90ae1400bf2 307 uint16_t * p_offset,
Vincent Coubard 638:c90ae1400bf2 308 uint16_t max_size)
Vincent Coubard 638:c90ae1400bf2 309 {
Vincent Coubard 638:c90ae1400bf2 310 // Check for buffer overflow.
Vincent Coubard 638:c90ae1400bf2 311 if (((*p_offset) + AD_TYPE_TX_POWER_LEVEL_SIZE) > max_size)
Vincent Coubard 638:c90ae1400bf2 312 {
Vincent Coubard 638:c90ae1400bf2 313 return NRF_ERROR_DATA_SIZE;
Vincent Coubard 638:c90ae1400bf2 314 }
Vincent Coubard 638:c90ae1400bf2 315
Vincent Coubard 638:c90ae1400bf2 316 // Encode TX Power Level.
Vincent Coubard 638:c90ae1400bf2 317 p_encoded_data[*p_offset] = (uint8_t)(ADV_AD_TYPE_FIELD_SIZE +
Vincent Coubard 638:c90ae1400bf2 318 AD_TYPE_TX_POWER_LEVEL_DATA_SIZE);
Vincent Coubard 638:c90ae1400bf2 319 *p_offset += ADV_LENGTH_FIELD_SIZE;
Vincent Coubard 638:c90ae1400bf2 320 p_encoded_data[*p_offset] = BLE_GAP_AD_TYPE_TX_POWER_LEVEL;
Vincent Coubard 638:c90ae1400bf2 321 *p_offset += ADV_AD_TYPE_FIELD_SIZE;
Vincent Coubard 638:c90ae1400bf2 322 p_encoded_data[*p_offset] = tx_power_level;
Vincent Coubard 638:c90ae1400bf2 323 *p_offset += AD_TYPE_TX_POWER_LEVEL_DATA_SIZE;
Vincent Coubard 638:c90ae1400bf2 324
Vincent Coubard 638:c90ae1400bf2 325 return NRF_SUCCESS;
Vincent Coubard 638:c90ae1400bf2 326 }
Vincent Coubard 638:c90ae1400bf2 327
Vincent Coubard 638:c90ae1400bf2 328
Vincent Coubard 638:c90ae1400bf2 329 static uint32_t uuid_list_sized_encode(const ble_advdata_uuid_list_t * p_uuid_list,
Vincent Coubard 638:c90ae1400bf2 330 uint8_t adv_type,
Vincent Coubard 638:c90ae1400bf2 331 uint8_t uuid_size,
Vincent Coubard 638:c90ae1400bf2 332 uint8_t * p_encoded_data,
Vincent Coubard 638:c90ae1400bf2 333 uint16_t * p_offset,
Vincent Coubard 638:c90ae1400bf2 334 uint16_t max_size)
Vincent Coubard 638:c90ae1400bf2 335 {
Vincent Coubard 638:c90ae1400bf2 336 int i;
Vincent Coubard 638:c90ae1400bf2 337 bool is_heading_written = false;
Vincent Coubard 638:c90ae1400bf2 338 uint16_t start_pos = *p_offset;
Vincent Coubard 638:c90ae1400bf2 339 uint16_t length;
Vincent Coubard 638:c90ae1400bf2 340
Vincent Coubard 638:c90ae1400bf2 341 for (i = 0; i < p_uuid_list->uuid_cnt; i++)
Vincent Coubard 638:c90ae1400bf2 342 {
Vincent Coubard 638:c90ae1400bf2 343 uint32_t err_code;
Vincent Coubard 638:c90ae1400bf2 344 uint8_t encoded_size;
Vincent Coubard 638:c90ae1400bf2 345 ble_uuid_t uuid = p_uuid_list->p_uuids[i];
Vincent Coubard 638:c90ae1400bf2 346
Vincent Coubard 638:c90ae1400bf2 347 // Find encoded uuid size.
Vincent Coubard 638:c90ae1400bf2 348 err_code = sd_ble_uuid_encode(&uuid, &encoded_size, NULL);
Vincent Coubard 638:c90ae1400bf2 349 if (err_code != NRF_SUCCESS)
Vincent Coubard 638:c90ae1400bf2 350 {
Vincent Coubard 638:c90ae1400bf2 351 return err_code;
Vincent Coubard 638:c90ae1400bf2 352 }
Vincent Coubard 638:c90ae1400bf2 353
Vincent Coubard 638:c90ae1400bf2 354 // Check size.
Vincent Coubard 638:c90ae1400bf2 355 if (encoded_size == uuid_size)
Vincent Coubard 638:c90ae1400bf2 356 {
Vincent Coubard 638:c90ae1400bf2 357 uint8_t heading_bytes = (is_heading_written) ? 0 : ADV_AD_DATA_OFFSET;
Vincent Coubard 638:c90ae1400bf2 358
Vincent Coubard 638:c90ae1400bf2 359 // Check for buffer overflow
Vincent Coubard 638:c90ae1400bf2 360 if (((*p_offset) + encoded_size + heading_bytes) > max_size)
Vincent Coubard 638:c90ae1400bf2 361 {
Vincent Coubard 638:c90ae1400bf2 362 return NRF_ERROR_DATA_SIZE;
Vincent Coubard 638:c90ae1400bf2 363 }
Vincent Coubard 638:c90ae1400bf2 364
Vincent Coubard 638:c90ae1400bf2 365 if (!is_heading_written)
Vincent Coubard 638:c90ae1400bf2 366 {
Vincent Coubard 638:c90ae1400bf2 367 // Write AD structure heading.
Vincent Coubard 638:c90ae1400bf2 368 *p_offset += ADV_LENGTH_FIELD_SIZE;
Vincent Coubard 638:c90ae1400bf2 369 p_encoded_data[*p_offset] = adv_type;
Vincent Coubard 638:c90ae1400bf2 370 *p_offset += ADV_AD_TYPE_FIELD_SIZE;
Vincent Coubard 638:c90ae1400bf2 371 is_heading_written = true;
Vincent Coubard 638:c90ae1400bf2 372 }
Vincent Coubard 638:c90ae1400bf2 373
Vincent Coubard 638:c90ae1400bf2 374 // Write UUID.
Vincent Coubard 638:c90ae1400bf2 375 err_code = sd_ble_uuid_encode(&uuid, &encoded_size, &p_encoded_data[*p_offset]);
Vincent Coubard 638:c90ae1400bf2 376 if (err_code != NRF_SUCCESS)
Vincent Coubard 638:c90ae1400bf2 377 {
Vincent Coubard 638:c90ae1400bf2 378 return err_code;
Vincent Coubard 638:c90ae1400bf2 379 }
Vincent Coubard 638:c90ae1400bf2 380 *p_offset += encoded_size;
Vincent Coubard 638:c90ae1400bf2 381 }
Vincent Coubard 638:c90ae1400bf2 382 }
Vincent Coubard 638:c90ae1400bf2 383
Vincent Coubard 638:c90ae1400bf2 384 if (is_heading_written)
Vincent Coubard 638:c90ae1400bf2 385 {
Vincent Coubard 638:c90ae1400bf2 386 // Write length.
Vincent Coubard 638:c90ae1400bf2 387 length = (*p_offset) - (start_pos + ADV_LENGTH_FIELD_SIZE);
Vincent Coubard 638:c90ae1400bf2 388 // There is only 1 byte intended to encode length
Vincent Coubard 638:c90ae1400bf2 389 if(length > 0x00FF)
Vincent Coubard 638:c90ae1400bf2 390 {
Vincent Coubard 638:c90ae1400bf2 391 return NRF_ERROR_DATA_SIZE;
Vincent Coubard 638:c90ae1400bf2 392 }
Vincent Coubard 638:c90ae1400bf2 393 p_encoded_data[start_pos] = (uint8_t)length;
Vincent Coubard 638:c90ae1400bf2 394 }
Vincent Coubard 638:c90ae1400bf2 395
Vincent Coubard 638:c90ae1400bf2 396 return NRF_SUCCESS;
Vincent Coubard 638:c90ae1400bf2 397 }
Vincent Coubard 638:c90ae1400bf2 398
Vincent Coubard 638:c90ae1400bf2 399
Vincent Coubard 638:c90ae1400bf2 400 static uint32_t uuid_list_encode(const ble_advdata_uuid_list_t * p_uuid_list,
Vincent Coubard 638:c90ae1400bf2 401 uint8_t adv_type_16,
Vincent Coubard 638:c90ae1400bf2 402 uint8_t adv_type_128,
Vincent Coubard 638:c90ae1400bf2 403 uint8_t * p_encoded_data,
Vincent Coubard 638:c90ae1400bf2 404 uint16_t * p_offset,
Vincent Coubard 638:c90ae1400bf2 405 uint16_t max_size)
Vincent Coubard 638:c90ae1400bf2 406 {
Vincent Coubard 638:c90ae1400bf2 407 uint32_t err_code;
Vincent Coubard 638:c90ae1400bf2 408
Vincent Coubard 638:c90ae1400bf2 409 // Encode 16 bit UUIDs.
Vincent Coubard 638:c90ae1400bf2 410 err_code = uuid_list_sized_encode(p_uuid_list,
Vincent Coubard 638:c90ae1400bf2 411 adv_type_16,
Vincent Coubard 638:c90ae1400bf2 412 sizeof(uint16_le_t),
Vincent Coubard 638:c90ae1400bf2 413 p_encoded_data,
Vincent Coubard 638:c90ae1400bf2 414 p_offset,
Vincent Coubard 638:c90ae1400bf2 415 max_size);
Vincent Coubard 638:c90ae1400bf2 416 if (err_code != NRF_SUCCESS)
Vincent Coubard 638:c90ae1400bf2 417 {
Vincent Coubard 638:c90ae1400bf2 418 return err_code;
Vincent Coubard 638:c90ae1400bf2 419 }
Vincent Coubard 638:c90ae1400bf2 420
Vincent Coubard 638:c90ae1400bf2 421 // Encode 128 bit UUIDs.
Vincent Coubard 638:c90ae1400bf2 422 err_code = uuid_list_sized_encode(p_uuid_list,
Vincent Coubard 638:c90ae1400bf2 423 adv_type_128,
Vincent Coubard 638:c90ae1400bf2 424 sizeof(ble_uuid128_t),
Vincent Coubard 638:c90ae1400bf2 425 p_encoded_data,
Vincent Coubard 638:c90ae1400bf2 426 p_offset,
Vincent Coubard 638:c90ae1400bf2 427 max_size);
Vincent Coubard 638:c90ae1400bf2 428 if (err_code != NRF_SUCCESS)
Vincent Coubard 638:c90ae1400bf2 429 {
Vincent Coubard 638:c90ae1400bf2 430 return err_code;
Vincent Coubard 638:c90ae1400bf2 431 }
Vincent Coubard 638:c90ae1400bf2 432
Vincent Coubard 638:c90ae1400bf2 433 return NRF_SUCCESS;
Vincent Coubard 638:c90ae1400bf2 434 }
Vincent Coubard 638:c90ae1400bf2 435
Vincent Coubard 638:c90ae1400bf2 436
Vincent Coubard 638:c90ae1400bf2 437 static uint32_t conn_int_check(const ble_advdata_conn_int_t *p_conn_int)
Vincent Coubard 638:c90ae1400bf2 438 {
Vincent Coubard 638:c90ae1400bf2 439 // Check Minimum Connection Interval.
Vincent Coubard 638:c90ae1400bf2 440 if ((p_conn_int->min_conn_interval < 0x0006) ||
Vincent Coubard 638:c90ae1400bf2 441 (
Vincent Coubard 638:c90ae1400bf2 442 (p_conn_int->min_conn_interval > 0x0c80) &&
Vincent Coubard 638:c90ae1400bf2 443 (p_conn_int->min_conn_interval != 0xffff)
Vincent Coubard 638:c90ae1400bf2 444 )
Vincent Coubard 638:c90ae1400bf2 445 )
Vincent Coubard 638:c90ae1400bf2 446 {
Vincent Coubard 638:c90ae1400bf2 447 return NRF_ERROR_INVALID_PARAM;
Vincent Coubard 638:c90ae1400bf2 448 }
Vincent Coubard 638:c90ae1400bf2 449
Vincent Coubard 638:c90ae1400bf2 450 // Check Maximum Connection Interval.
Vincent Coubard 638:c90ae1400bf2 451 if ((p_conn_int->max_conn_interval < 0x0006) ||
Vincent Coubard 638:c90ae1400bf2 452 (
Vincent Coubard 638:c90ae1400bf2 453 (p_conn_int->max_conn_interval > 0x0c80) &&
Vincent Coubard 638:c90ae1400bf2 454 (p_conn_int->max_conn_interval != 0xffff)
Vincent Coubard 638:c90ae1400bf2 455 )
Vincent Coubard 638:c90ae1400bf2 456 )
Vincent Coubard 638:c90ae1400bf2 457 {
Vincent Coubard 638:c90ae1400bf2 458 return NRF_ERROR_INVALID_PARAM;
Vincent Coubard 638:c90ae1400bf2 459 }
Vincent Coubard 638:c90ae1400bf2 460
Vincent Coubard 638:c90ae1400bf2 461 // Make sure Minimum Connection Interval is not bigger than Maximum Connection Interval.
Vincent Coubard 638:c90ae1400bf2 462 if ((p_conn_int->min_conn_interval != 0xffff) &&
Vincent Coubard 638:c90ae1400bf2 463 (p_conn_int->max_conn_interval != 0xffff) &&
Vincent Coubard 638:c90ae1400bf2 464 (p_conn_int->min_conn_interval > p_conn_int->max_conn_interval)
Vincent Coubard 638:c90ae1400bf2 465 )
Vincent Coubard 638:c90ae1400bf2 466 {
Vincent Coubard 638:c90ae1400bf2 467 return NRF_ERROR_INVALID_PARAM;
Vincent Coubard 638:c90ae1400bf2 468 }
Vincent Coubard 638:c90ae1400bf2 469
Vincent Coubard 638:c90ae1400bf2 470 return NRF_SUCCESS;
Vincent Coubard 638:c90ae1400bf2 471 }
Vincent Coubard 638:c90ae1400bf2 472
Vincent Coubard 638:c90ae1400bf2 473
Vincent Coubard 638:c90ae1400bf2 474 static uint32_t conn_int_encode(const ble_advdata_conn_int_t * p_conn_int,
Vincent Coubard 638:c90ae1400bf2 475 uint8_t * p_encoded_data,
Vincent Coubard 638:c90ae1400bf2 476 uint16_t * p_offset,
Vincent Coubard 638:c90ae1400bf2 477 uint16_t max_size)
Vincent Coubard 638:c90ae1400bf2 478 {
Vincent Coubard 638:c90ae1400bf2 479 uint32_t err_code;
Vincent Coubard 638:c90ae1400bf2 480
Vincent Coubard 638:c90ae1400bf2 481 // Check for buffer overflow.
Vincent Coubard 638:c90ae1400bf2 482 if (((*p_offset) + AD_TYPE_CONN_INT_SIZE) > max_size)
Vincent Coubard 638:c90ae1400bf2 483 {
Vincent Coubard 638:c90ae1400bf2 484 return NRF_ERROR_DATA_SIZE;
Vincent Coubard 638:c90ae1400bf2 485 }
Vincent Coubard 638:c90ae1400bf2 486
Vincent Coubard 638:c90ae1400bf2 487 // Check parameters.
Vincent Coubard 638:c90ae1400bf2 488 err_code = conn_int_check(p_conn_int);
Vincent Coubard 638:c90ae1400bf2 489 if (err_code != NRF_SUCCESS)
Vincent Coubard 638:c90ae1400bf2 490 {
Vincent Coubard 638:c90ae1400bf2 491 return err_code;
Vincent Coubard 638:c90ae1400bf2 492 }
Vincent Coubard 638:c90ae1400bf2 493
Vincent Coubard 638:c90ae1400bf2 494 // Encode Length and AD Type.
Vincent Coubard 638:c90ae1400bf2 495 p_encoded_data[*p_offset] = (uint8_t)(ADV_AD_TYPE_FIELD_SIZE + AD_TYPE_CONN_INT_DATA_SIZE);
Vincent Coubard 638:c90ae1400bf2 496 *p_offset += ADV_LENGTH_FIELD_SIZE;
Vincent Coubard 638:c90ae1400bf2 497 p_encoded_data[*p_offset] = BLE_GAP_AD_TYPE_SLAVE_CONNECTION_INTERVAL_RANGE;
Vincent Coubard 638:c90ae1400bf2 498 *p_offset += ADV_AD_TYPE_FIELD_SIZE;
Vincent Coubard 638:c90ae1400bf2 499
Vincent Coubard 638:c90ae1400bf2 500 // Encode Minimum and Maximum Connection Intervals.
Vincent Coubard 638:c90ae1400bf2 501 *p_offset += uint16_encode(p_conn_int->min_conn_interval, &p_encoded_data[*p_offset]);
Vincent Coubard 638:c90ae1400bf2 502 *p_offset += uint16_encode(p_conn_int->max_conn_interval, &p_encoded_data[*p_offset]);
Vincent Coubard 638:c90ae1400bf2 503
Vincent Coubard 638:c90ae1400bf2 504 return NRF_SUCCESS;
Vincent Coubard 638:c90ae1400bf2 505 }
Vincent Coubard 638:c90ae1400bf2 506
Vincent Coubard 638:c90ae1400bf2 507
Vincent Coubard 638:c90ae1400bf2 508 static uint32_t manuf_specific_data_encode(const ble_advdata_manuf_data_t * p_manuf_sp_data,
Vincent Coubard 638:c90ae1400bf2 509 uint8_t * p_encoded_data,
Vincent Coubard 638:c90ae1400bf2 510 uint16_t * p_offset,
Vincent Coubard 638:c90ae1400bf2 511 uint16_t max_size)
Vincent Coubard 638:c90ae1400bf2 512 {
Vincent Coubard 638:c90ae1400bf2 513 uint32_t data_size = AD_TYPE_MANUF_SPEC_DATA_ID_SIZE + p_manuf_sp_data->data.size;
Vincent Coubard 638:c90ae1400bf2 514
Vincent Coubard 638:c90ae1400bf2 515 // Check for buffer overflow.
Vincent Coubard 638:c90ae1400bf2 516 if (((*p_offset) + ADV_AD_DATA_OFFSET + data_size) > max_size)
Vincent Coubard 638:c90ae1400bf2 517 {
Vincent Coubard 638:c90ae1400bf2 518 return NRF_ERROR_DATA_SIZE;
Vincent Coubard 638:c90ae1400bf2 519 }
Vincent Coubard 638:c90ae1400bf2 520
Vincent Coubard 638:c90ae1400bf2 521 // There is only 1 byte intended to encode length which is (data_size + ADV_AD_TYPE_FIELD_SIZE)
Vincent Coubard 638:c90ae1400bf2 522 if(data_size > (0x00FF - ADV_AD_TYPE_FIELD_SIZE))
Vincent Coubard 638:c90ae1400bf2 523 {
Vincent Coubard 638:c90ae1400bf2 524 return NRF_ERROR_DATA_SIZE;
Vincent Coubard 638:c90ae1400bf2 525 }
Vincent Coubard 638:c90ae1400bf2 526
Vincent Coubard 638:c90ae1400bf2 527 // Encode Length and AD Type.
Vincent Coubard 638:c90ae1400bf2 528 p_encoded_data[*p_offset] = (uint8_t)(ADV_AD_TYPE_FIELD_SIZE + data_size);
Vincent Coubard 638:c90ae1400bf2 529 *p_offset += ADV_LENGTH_FIELD_SIZE;
Vincent Coubard 638:c90ae1400bf2 530 p_encoded_data[*p_offset] = BLE_GAP_AD_TYPE_MANUFACTURER_SPECIFIC_DATA;
Vincent Coubard 638:c90ae1400bf2 531 *p_offset += ADV_AD_TYPE_FIELD_SIZE;
Vincent Coubard 638:c90ae1400bf2 532
Vincent Coubard 638:c90ae1400bf2 533 // Encode Company Identifier.
Vincent Coubard 638:c90ae1400bf2 534 *p_offset += uint16_encode(p_manuf_sp_data->company_identifier, &p_encoded_data[*p_offset]);
Vincent Coubard 638:c90ae1400bf2 535
Vincent Coubard 638:c90ae1400bf2 536 // Encode additional manufacturer specific data.
Vincent Coubard 638:c90ae1400bf2 537 if (p_manuf_sp_data->data.size > 0)
Vincent Coubard 638:c90ae1400bf2 538 {
Vincent Coubard 638:c90ae1400bf2 539 if (p_manuf_sp_data->data.p_data == NULL)
Vincent Coubard 638:c90ae1400bf2 540 {
Vincent Coubard 638:c90ae1400bf2 541 return NRF_ERROR_INVALID_PARAM;
Vincent Coubard 638:c90ae1400bf2 542 }
Vincent Coubard 638:c90ae1400bf2 543 memcpy(&p_encoded_data[*p_offset], p_manuf_sp_data->data.p_data, p_manuf_sp_data->data.size);
Vincent Coubard 638:c90ae1400bf2 544 *p_offset += p_manuf_sp_data->data.size;
Vincent Coubard 638:c90ae1400bf2 545 }
Vincent Coubard 638:c90ae1400bf2 546
Vincent Coubard 638:c90ae1400bf2 547 return NRF_SUCCESS;
Vincent Coubard 638:c90ae1400bf2 548 }
Vincent Coubard 638:c90ae1400bf2 549
Vincent Coubard 638:c90ae1400bf2 550 // Implemented only for 16-bit UUIDs
Vincent Coubard 638:c90ae1400bf2 551 static uint32_t service_data_encode(const ble_advdata_t * p_advdata,
Vincent Coubard 638:c90ae1400bf2 552 uint8_t * p_encoded_data,
Vincent Coubard 638:c90ae1400bf2 553 uint16_t * p_offset,
Vincent Coubard 638:c90ae1400bf2 554 uint16_t max_size)
Vincent Coubard 638:c90ae1400bf2 555 {
Vincent Coubard 638:c90ae1400bf2 556 uint8_t i;
Vincent Coubard 638:c90ae1400bf2 557
Vincent Coubard 638:c90ae1400bf2 558 // Check parameter consistency.
Vincent Coubard 638:c90ae1400bf2 559 if (p_advdata->p_service_data_array == NULL)
Vincent Coubard 638:c90ae1400bf2 560 {
Vincent Coubard 638:c90ae1400bf2 561 return NRF_ERROR_INVALID_PARAM;
Vincent Coubard 638:c90ae1400bf2 562 }
Vincent Coubard 638:c90ae1400bf2 563
Vincent Coubard 638:c90ae1400bf2 564 for (i = 0; i < p_advdata->service_data_count; i++)
Vincent Coubard 638:c90ae1400bf2 565 {
Vincent Coubard 638:c90ae1400bf2 566 ble_advdata_service_data_t * p_service_data;
Vincent Coubard 638:c90ae1400bf2 567 uint32_t data_size;
Vincent Coubard 638:c90ae1400bf2 568
Vincent Coubard 638:c90ae1400bf2 569 p_service_data = &p_advdata->p_service_data_array[i];
Vincent Coubard 638:c90ae1400bf2 570 // For now implemented only for 16-bit UUIDs
Vincent Coubard 638:c90ae1400bf2 571 data_size = AD_TYPE_SERV_DATA_16BIT_UUID_SIZE + p_service_data->data.size;
Vincent Coubard 638:c90ae1400bf2 572
Vincent Coubard 638:c90ae1400bf2 573 // There is only 1 byte intended to encode length which is (data_size + ADV_AD_TYPE_FIELD_SIZE)
Vincent Coubard 638:c90ae1400bf2 574 if(data_size > (0x00FF - ADV_AD_TYPE_FIELD_SIZE))
Vincent Coubard 638:c90ae1400bf2 575 {
Vincent Coubard 638:c90ae1400bf2 576 return NRF_ERROR_DATA_SIZE;
Vincent Coubard 638:c90ae1400bf2 577 }
Vincent Coubard 638:c90ae1400bf2 578
Vincent Coubard 638:c90ae1400bf2 579 // Encode Length and AD Type.
Vincent Coubard 638:c90ae1400bf2 580 p_encoded_data[*p_offset] = (uint8_t)(ADV_AD_TYPE_FIELD_SIZE + data_size);
Vincent Coubard 638:c90ae1400bf2 581 *p_offset += ADV_LENGTH_FIELD_SIZE;
Vincent Coubard 638:c90ae1400bf2 582 p_encoded_data[*p_offset] = BLE_GAP_AD_TYPE_SERVICE_DATA;
Vincent Coubard 638:c90ae1400bf2 583 *p_offset += ADV_AD_TYPE_FIELD_SIZE;
Vincent Coubard 638:c90ae1400bf2 584
Vincent Coubard 638:c90ae1400bf2 585 // Encode service 16-bit UUID.
Vincent Coubard 638:c90ae1400bf2 586 *p_offset += uint16_encode(p_service_data->service_uuid, &p_encoded_data[*p_offset]);
Vincent Coubard 638:c90ae1400bf2 587
Vincent Coubard 638:c90ae1400bf2 588 // Encode additional service data.
Vincent Coubard 638:c90ae1400bf2 589 if (p_service_data->data.size > 0)
Vincent Coubard 638:c90ae1400bf2 590 {
Vincent Coubard 638:c90ae1400bf2 591 if (p_service_data->data.p_data == NULL)
Vincent Coubard 638:c90ae1400bf2 592 {
Vincent Coubard 638:c90ae1400bf2 593 return NRF_ERROR_INVALID_PARAM;
Vincent Coubard 638:c90ae1400bf2 594 }
Vincent Coubard 638:c90ae1400bf2 595 memcpy(&p_encoded_data[*p_offset], p_service_data->data.p_data, p_service_data->data.size);
Vincent Coubard 638:c90ae1400bf2 596 *p_offset += p_service_data->data.size;
Vincent Coubard 638:c90ae1400bf2 597 }
Vincent Coubard 638:c90ae1400bf2 598 }
Vincent Coubard 638:c90ae1400bf2 599
Vincent Coubard 638:c90ae1400bf2 600 return NRF_SUCCESS;
Vincent Coubard 638:c90ae1400bf2 601 }
Vincent Coubard 638:c90ae1400bf2 602
Vincent Coubard 638:c90ae1400bf2 603 uint32_t adv_data_encode(ble_advdata_t const * const p_advdata,
Vincent Coubard 638:c90ae1400bf2 604 uint8_t * const p_encoded_data,
Vincent Coubard 638:c90ae1400bf2 605 uint16_t * const p_len)
Vincent Coubard 638:c90ae1400bf2 606 {
Vincent Coubard 638:c90ae1400bf2 607 uint32_t err_code = NRF_SUCCESS;
Vincent Coubard 638:c90ae1400bf2 608 uint16_t max_size = *p_len;
Vincent Coubard 638:c90ae1400bf2 609 *p_len = 0;
Vincent Coubard 638:c90ae1400bf2 610
Vincent Coubard 638:c90ae1400bf2 611 //Encode Security Manager OOB Flags
Vincent Coubard 638:c90ae1400bf2 612 if (p_advdata->p_sec_mgr_oob_flags != NULL)
Vincent Coubard 638:c90ae1400bf2 613 {
Vincent Coubard 638:c90ae1400bf2 614 err_code = sec_mgr_oob_flags_encode(*p_advdata->p_sec_mgr_oob_flags,
Vincent Coubard 638:c90ae1400bf2 615 p_encoded_data,
Vincent Coubard 638:c90ae1400bf2 616 p_len,
Vincent Coubard 638:c90ae1400bf2 617 max_size);
Vincent Coubard 638:c90ae1400bf2 618 if (err_code != NRF_SUCCESS)
Vincent Coubard 638:c90ae1400bf2 619 {
Vincent Coubard 638:c90ae1400bf2 620 return err_code;
Vincent Coubard 638:c90ae1400bf2 621 }
Vincent Coubard 638:c90ae1400bf2 622 }
Vincent Coubard 638:c90ae1400bf2 623
Vincent Coubard 638:c90ae1400bf2 624 // Encode Security Manager TK value
Vincent Coubard 638:c90ae1400bf2 625 if (NULL != p_advdata->p_tk_value)
Vincent Coubard 638:c90ae1400bf2 626 {
Vincent Coubard 638:c90ae1400bf2 627 err_code = tk_value_encode(p_advdata->p_tk_value, p_encoded_data, p_len, max_size);
Vincent Coubard 638:c90ae1400bf2 628 if (err_code != NRF_SUCCESS)
Vincent Coubard 638:c90ae1400bf2 629 {
Vincent Coubard 638:c90ae1400bf2 630 return err_code;
Vincent Coubard 638:c90ae1400bf2 631 }
Vincent Coubard 638:c90ae1400bf2 632 }
Vincent Coubard 638:c90ae1400bf2 633
Vincent Coubard 638:c90ae1400bf2 634 // Encode LE Role
Vincent Coubard 638:c90ae1400bf2 635 if (BLE_ADVDATA_ROLE_NOT_PRESENT != p_advdata->le_role)
Vincent Coubard 638:c90ae1400bf2 636 {
Vincent Coubard 638:c90ae1400bf2 637 err_code = le_role_encode(p_advdata->le_role, p_encoded_data, p_len, max_size);
Vincent Coubard 638:c90ae1400bf2 638 if (err_code != NRF_SUCCESS)
Vincent Coubard 638:c90ae1400bf2 639 {
Vincent Coubard 638:c90ae1400bf2 640 return err_code;
Vincent Coubard 638:c90ae1400bf2 641 }
Vincent Coubard 638:c90ae1400bf2 642 }
Vincent Coubard 638:c90ae1400bf2 643
Vincent Coubard 638:c90ae1400bf2 644 // Encode LE Bluetooth Device Address
Vincent Coubard 638:c90ae1400bf2 645 if (p_advdata->include_ble_device_addr)
Vincent Coubard 638:c90ae1400bf2 646 {
Vincent Coubard 638:c90ae1400bf2 647 err_code = ble_device_addr_encode(p_encoded_data, p_len, max_size);
Vincent Coubard 638:c90ae1400bf2 648 if (err_code != NRF_SUCCESS)
Vincent Coubard 638:c90ae1400bf2 649 {
Vincent Coubard 638:c90ae1400bf2 650 return err_code;
Vincent Coubard 638:c90ae1400bf2 651 }
Vincent Coubard 638:c90ae1400bf2 652 }
Vincent Coubard 638:c90ae1400bf2 653
Vincent Coubard 638:c90ae1400bf2 654 // Encode appearance.
Vincent Coubard 638:c90ae1400bf2 655 if (p_advdata->include_appearance)
Vincent Coubard 638:c90ae1400bf2 656 {
Vincent Coubard 638:c90ae1400bf2 657 err_code = appearance_encode(p_encoded_data, p_len, max_size);
Vincent Coubard 638:c90ae1400bf2 658 if (err_code != NRF_SUCCESS)
Vincent Coubard 638:c90ae1400bf2 659 {
Vincent Coubard 638:c90ae1400bf2 660 return err_code;
Vincent Coubard 638:c90ae1400bf2 661 }
Vincent Coubard 638:c90ae1400bf2 662 }
Vincent Coubard 638:c90ae1400bf2 663
Vincent Coubard 638:c90ae1400bf2 664 //Encode Flags
Vincent Coubard 638:c90ae1400bf2 665 if(p_advdata->flags != 0 )
Vincent Coubard 638:c90ae1400bf2 666 {
Vincent Coubard 638:c90ae1400bf2 667 err_code = flags_encode(p_advdata->flags, p_encoded_data, p_len, max_size);
Vincent Coubard 638:c90ae1400bf2 668 if (err_code != NRF_SUCCESS)
Vincent Coubard 638:c90ae1400bf2 669 {
Vincent Coubard 638:c90ae1400bf2 670 return err_code;
Vincent Coubard 638:c90ae1400bf2 671 }
Vincent Coubard 638:c90ae1400bf2 672 }
Vincent Coubard 638:c90ae1400bf2 673
Vincent Coubard 638:c90ae1400bf2 674 // Encode TX power level.
Vincent Coubard 638:c90ae1400bf2 675 if (p_advdata->p_tx_power_level != NULL)
Vincent Coubard 638:c90ae1400bf2 676 {
Vincent Coubard 638:c90ae1400bf2 677 err_code = tx_power_level_encode(*p_advdata->p_tx_power_level,
Vincent Coubard 638:c90ae1400bf2 678 p_encoded_data,
Vincent Coubard 638:c90ae1400bf2 679 p_len,
Vincent Coubard 638:c90ae1400bf2 680 max_size);
Vincent Coubard 638:c90ae1400bf2 681 if (err_code != NRF_SUCCESS)
Vincent Coubard 638:c90ae1400bf2 682 {
Vincent Coubard 638:c90ae1400bf2 683 return err_code;
Vincent Coubard 638:c90ae1400bf2 684 }
Vincent Coubard 638:c90ae1400bf2 685 }
Vincent Coubard 638:c90ae1400bf2 686
Vincent Coubard 638:c90ae1400bf2 687 // Encode 'more available' uuid list.
Vincent Coubard 638:c90ae1400bf2 688 if (p_advdata->uuids_more_available.uuid_cnt > 0)
Vincent Coubard 638:c90ae1400bf2 689 {
Vincent Coubard 638:c90ae1400bf2 690 err_code = uuid_list_encode(&p_advdata->uuids_more_available,
Vincent Coubard 638:c90ae1400bf2 691 BLE_GAP_AD_TYPE_16BIT_SERVICE_UUID_MORE_AVAILABLE,
Vincent Coubard 638:c90ae1400bf2 692 BLE_GAP_AD_TYPE_128BIT_SERVICE_UUID_MORE_AVAILABLE,
Vincent Coubard 638:c90ae1400bf2 693 p_encoded_data,
Vincent Coubard 638:c90ae1400bf2 694 p_len,
Vincent Coubard 638:c90ae1400bf2 695 max_size);
Vincent Coubard 638:c90ae1400bf2 696 if (err_code != NRF_SUCCESS)
Vincent Coubard 638:c90ae1400bf2 697 {
Vincent Coubard 638:c90ae1400bf2 698 return err_code;
Vincent Coubard 638:c90ae1400bf2 699 }
Vincent Coubard 638:c90ae1400bf2 700 }
Vincent Coubard 638:c90ae1400bf2 701
Vincent Coubard 638:c90ae1400bf2 702 // Encode 'complete' uuid list.
Vincent Coubard 638:c90ae1400bf2 703 if (p_advdata->uuids_complete.uuid_cnt > 0)
Vincent Coubard 638:c90ae1400bf2 704 {
Vincent Coubard 638:c90ae1400bf2 705 err_code = uuid_list_encode(&p_advdata->uuids_complete,
Vincent Coubard 638:c90ae1400bf2 706 BLE_GAP_AD_TYPE_16BIT_SERVICE_UUID_COMPLETE,
Vincent Coubard 638:c90ae1400bf2 707 BLE_GAP_AD_TYPE_128BIT_SERVICE_UUID_COMPLETE,
Vincent Coubard 638:c90ae1400bf2 708 p_encoded_data,
Vincent Coubard 638:c90ae1400bf2 709 p_len,
Vincent Coubard 638:c90ae1400bf2 710 max_size);
Vincent Coubard 638:c90ae1400bf2 711 if (err_code != NRF_SUCCESS)
Vincent Coubard 638:c90ae1400bf2 712 {
Vincent Coubard 638:c90ae1400bf2 713 return err_code;
Vincent Coubard 638:c90ae1400bf2 714 }
Vincent Coubard 638:c90ae1400bf2 715 }
Vincent Coubard 638:c90ae1400bf2 716
Vincent Coubard 638:c90ae1400bf2 717 // Encode 'solicited service' uuid list.
Vincent Coubard 638:c90ae1400bf2 718 if (p_advdata->uuids_solicited.uuid_cnt > 0)
Vincent Coubard 638:c90ae1400bf2 719 {
Vincent Coubard 638:c90ae1400bf2 720 err_code = uuid_list_encode(&p_advdata->uuids_solicited,
Vincent Coubard 638:c90ae1400bf2 721 BLE_GAP_AD_TYPE_SOLICITED_SERVICE_UUIDS_16BIT,
Vincent Coubard 638:c90ae1400bf2 722 BLE_GAP_AD_TYPE_SOLICITED_SERVICE_UUIDS_128BIT,
Vincent Coubard 638:c90ae1400bf2 723 p_encoded_data,
Vincent Coubard 638:c90ae1400bf2 724 p_len,
Vincent Coubard 638:c90ae1400bf2 725 max_size);
Vincent Coubard 638:c90ae1400bf2 726 if (err_code != NRF_SUCCESS)
Vincent Coubard 638:c90ae1400bf2 727 {
Vincent Coubard 638:c90ae1400bf2 728 return err_code;
Vincent Coubard 638:c90ae1400bf2 729 }
Vincent Coubard 638:c90ae1400bf2 730 }
Vincent Coubard 638:c90ae1400bf2 731
Vincent Coubard 638:c90ae1400bf2 732 // Encode Slave Connection Interval Range.
Vincent Coubard 638:c90ae1400bf2 733 if (p_advdata->p_slave_conn_int != NULL)
Vincent Coubard 638:c90ae1400bf2 734 {
Vincent Coubard 638:c90ae1400bf2 735 err_code = conn_int_encode(p_advdata->p_slave_conn_int, p_encoded_data, p_len, max_size);
Vincent Coubard 638:c90ae1400bf2 736 if (err_code != NRF_SUCCESS)
Vincent Coubard 638:c90ae1400bf2 737 {
Vincent Coubard 638:c90ae1400bf2 738 return err_code;
Vincent Coubard 638:c90ae1400bf2 739 }
Vincent Coubard 638:c90ae1400bf2 740 }
Vincent Coubard 638:c90ae1400bf2 741
Vincent Coubard 638:c90ae1400bf2 742 // Encode Manufacturer Specific Data.
Vincent Coubard 638:c90ae1400bf2 743 if (p_advdata->p_manuf_specific_data != NULL)
Vincent Coubard 638:c90ae1400bf2 744 {
Vincent Coubard 638:c90ae1400bf2 745 err_code = manuf_specific_data_encode(p_advdata->p_manuf_specific_data,
Vincent Coubard 638:c90ae1400bf2 746 p_encoded_data,
Vincent Coubard 638:c90ae1400bf2 747 p_len,
Vincent Coubard 638:c90ae1400bf2 748 max_size);
Vincent Coubard 638:c90ae1400bf2 749 if (err_code != NRF_SUCCESS)
Vincent Coubard 638:c90ae1400bf2 750 {
Vincent Coubard 638:c90ae1400bf2 751 return err_code;
Vincent Coubard 638:c90ae1400bf2 752 }
Vincent Coubard 638:c90ae1400bf2 753 }
Vincent Coubard 638:c90ae1400bf2 754
Vincent Coubard 638:c90ae1400bf2 755 // Encode Service Data.
Vincent Coubard 638:c90ae1400bf2 756 if (p_advdata->service_data_count > 0)
Vincent Coubard 638:c90ae1400bf2 757 {
Vincent Coubard 638:c90ae1400bf2 758 err_code = service_data_encode(p_advdata, p_encoded_data, p_len, max_size);
Vincent Coubard 638:c90ae1400bf2 759 if (err_code != NRF_SUCCESS)
Vincent Coubard 638:c90ae1400bf2 760 {
Vincent Coubard 638:c90ae1400bf2 761 return err_code;
Vincent Coubard 638:c90ae1400bf2 762 }
Vincent Coubard 638:c90ae1400bf2 763 }
Vincent Coubard 638:c90ae1400bf2 764
Vincent Coubard 638:c90ae1400bf2 765 // Encode name. WARNING: it is encoded last on purpose since too long device name is truncated.
Vincent Coubard 638:c90ae1400bf2 766 if (p_advdata->name_type != BLE_ADVDATA_NO_NAME)
Vincent Coubard 638:c90ae1400bf2 767 {
Vincent Coubard 638:c90ae1400bf2 768 err_code = name_encode(p_advdata, p_encoded_data, p_len, max_size);
Vincent Coubard 638:c90ae1400bf2 769 if (err_code != NRF_SUCCESS)
Vincent Coubard 638:c90ae1400bf2 770 {
Vincent Coubard 638:c90ae1400bf2 771 return err_code;
Vincent Coubard 638:c90ae1400bf2 772 }
Vincent Coubard 638:c90ae1400bf2 773 }
Vincent Coubard 638:c90ae1400bf2 774
Vincent Coubard 638:c90ae1400bf2 775 return err_code;
Vincent Coubard 638:c90ae1400bf2 776 }
Vincent Coubard 638:c90ae1400bf2 777
Vincent Coubard 638:c90ae1400bf2 778
Vincent Coubard 638:c90ae1400bf2 779 static uint32_t advdata_check(const ble_advdata_t * p_advdata)
Vincent Coubard 638:c90ae1400bf2 780 {
Vincent Coubard 638:c90ae1400bf2 781 // Flags must be included in advertising data, and the BLE_GAP_ADV_FLAG_BR_EDR_NOT_SUPPORTED flag must be set.
Vincent Coubard 638:c90ae1400bf2 782 if (
Vincent Coubard 638:c90ae1400bf2 783 ((p_advdata->flags & BLE_GAP_ADV_FLAG_BR_EDR_NOT_SUPPORTED) == 0)
Vincent Coubard 638:c90ae1400bf2 784 )
Vincent Coubard 638:c90ae1400bf2 785 {
Vincent Coubard 638:c90ae1400bf2 786 return NRF_ERROR_INVALID_PARAM;
Vincent Coubard 638:c90ae1400bf2 787 }
Vincent Coubard 638:c90ae1400bf2 788
Vincent Coubard 638:c90ae1400bf2 789 return NRF_SUCCESS;
Vincent Coubard 638:c90ae1400bf2 790 }
Vincent Coubard 638:c90ae1400bf2 791
Vincent Coubard 638:c90ae1400bf2 792
Vincent Coubard 638:c90ae1400bf2 793 static uint32_t srdata_check(const ble_advdata_t * p_srdata)
Vincent Coubard 638:c90ae1400bf2 794 {
Vincent Coubard 638:c90ae1400bf2 795 // Flags shall not be included in the scan response data.
Vincent Coubard 638:c90ae1400bf2 796 if (p_srdata->flags)
Vincent Coubard 638:c90ae1400bf2 797 {
Vincent Coubard 638:c90ae1400bf2 798 return NRF_ERROR_INVALID_PARAM;
Vincent Coubard 638:c90ae1400bf2 799 }
Vincent Coubard 638:c90ae1400bf2 800
Vincent Coubard 638:c90ae1400bf2 801 return NRF_SUCCESS;
Vincent Coubard 638:c90ae1400bf2 802 }
Vincent Coubard 638:c90ae1400bf2 803
Vincent Coubard 638:c90ae1400bf2 804
Vincent Coubard 638:c90ae1400bf2 805 uint32_t ble_advdata_set(const ble_advdata_t * p_advdata, const ble_advdata_t * p_srdata)
Vincent Coubard 638:c90ae1400bf2 806 {
Vincent Coubard 638:c90ae1400bf2 807 uint32_t err_code;
Vincent Coubard 638:c90ae1400bf2 808 uint16_t len_advdata = BLE_GAP_ADV_MAX_SIZE;
Vincent Coubard 638:c90ae1400bf2 809 uint16_t len_srdata = BLE_GAP_ADV_MAX_SIZE;
Vincent Coubard 638:c90ae1400bf2 810 uint8_t encoded_advdata[BLE_GAP_ADV_MAX_SIZE];
Vincent Coubard 638:c90ae1400bf2 811 uint8_t encoded_srdata[BLE_GAP_ADV_MAX_SIZE];
Vincent Coubard 638:c90ae1400bf2 812 uint8_t * p_encoded_advdata;
Vincent Coubard 638:c90ae1400bf2 813 uint8_t * p_encoded_srdata;
Vincent Coubard 638:c90ae1400bf2 814
Vincent Coubard 638:c90ae1400bf2 815 // Encode advertising data (if supplied).
Vincent Coubard 638:c90ae1400bf2 816 if (p_advdata != NULL)
Vincent Coubard 638:c90ae1400bf2 817 {
Vincent Coubard 638:c90ae1400bf2 818 err_code = advdata_check(p_advdata);
Vincent Coubard 638:c90ae1400bf2 819 if (err_code != NRF_SUCCESS)
Vincent Coubard 638:c90ae1400bf2 820 {
Vincent Coubard 638:c90ae1400bf2 821 return err_code;
Vincent Coubard 638:c90ae1400bf2 822 }
Vincent Coubard 638:c90ae1400bf2 823
Vincent Coubard 638:c90ae1400bf2 824 err_code = adv_data_encode(p_advdata, encoded_advdata, &len_advdata);
Vincent Coubard 638:c90ae1400bf2 825 if (err_code != NRF_SUCCESS)
Vincent Coubard 638:c90ae1400bf2 826 {
Vincent Coubard 638:c90ae1400bf2 827 return err_code;
Vincent Coubard 638:c90ae1400bf2 828 }
Vincent Coubard 638:c90ae1400bf2 829 p_encoded_advdata = encoded_advdata;
Vincent Coubard 638:c90ae1400bf2 830 }
Vincent Coubard 638:c90ae1400bf2 831 else
Vincent Coubard 638:c90ae1400bf2 832 {
Vincent Coubard 638:c90ae1400bf2 833 p_encoded_advdata = NULL;
Vincent Coubard 638:c90ae1400bf2 834 len_advdata = 0;
Vincent Coubard 638:c90ae1400bf2 835 }
Vincent Coubard 638:c90ae1400bf2 836
Vincent Coubard 638:c90ae1400bf2 837 // Encode scan response data (if supplied).
Vincent Coubard 638:c90ae1400bf2 838 if (p_srdata != NULL)
Vincent Coubard 638:c90ae1400bf2 839 {
Vincent Coubard 638:c90ae1400bf2 840 err_code = srdata_check(p_srdata);
Vincent Coubard 638:c90ae1400bf2 841 if (err_code != NRF_SUCCESS)
Vincent Coubard 638:c90ae1400bf2 842 {
Vincent Coubard 638:c90ae1400bf2 843 return err_code;
Vincent Coubard 638:c90ae1400bf2 844 }
Vincent Coubard 638:c90ae1400bf2 845
Vincent Coubard 638:c90ae1400bf2 846 err_code = adv_data_encode(p_srdata, encoded_srdata, &len_srdata);
Vincent Coubard 638:c90ae1400bf2 847 if (err_code != NRF_SUCCESS)
Vincent Coubard 638:c90ae1400bf2 848 {
Vincent Coubard 638:c90ae1400bf2 849 return err_code;
Vincent Coubard 638:c90ae1400bf2 850 }
Vincent Coubard 638:c90ae1400bf2 851 p_encoded_srdata = encoded_srdata;
Vincent Coubard 638:c90ae1400bf2 852 }
Vincent Coubard 638:c90ae1400bf2 853 else
Vincent Coubard 638:c90ae1400bf2 854 {
Vincent Coubard 638:c90ae1400bf2 855 p_encoded_srdata = NULL;
Vincent Coubard 638:c90ae1400bf2 856 len_srdata = 0;
Vincent Coubard 638:c90ae1400bf2 857 }
Vincent Coubard 638:c90ae1400bf2 858
Vincent Coubard 638:c90ae1400bf2 859 // Pass encoded advertising data and/or scan response data to the stack.
Vincent Coubard 638:c90ae1400bf2 860 return sd_ble_gap_adv_data_set(p_encoded_advdata, len_advdata, p_encoded_srdata, len_srdata);
Vincent Coubard 638:c90ae1400bf2 861 }