bugfix for duplicate symbol

Fork of nRF51822 by Nordic Semiconductor

Committer:
rgrover1
Date:
Thu Apr 30 08:34:37 2015 +0100
Revision:
112:737b08b3b995
Parent:
103:138bdc859cc9
Synchronized with git rev 4ae92f89
Author: Rohit Grover
porting to v8.0 of the SDK

Who changed what in which revision?

UserRevisionLine numberNew contents of line
rgrover1 103:138bdc859cc9 1 /* Copyright (c) 2012 Nordic Semiconductor. All Rights Reserved.
rgrover1 103:138bdc859cc9 2 *
rgrover1 103:138bdc859cc9 3 * The information contained herein is property of Nordic Semiconductor ASA.
rgrover1 103:138bdc859cc9 4 * Terms and conditions of usage are described in detail in NORDIC
rgrover1 103:138bdc859cc9 5 * SEMICONDUCTOR STANDARD SOFTWARE LICENSE AGREEMENT.
rgrover1 103:138bdc859cc9 6 *
rgrover1 103:138bdc859cc9 7 * Licensees are granted free, non-transferable use of the information. NO
rgrover1 103:138bdc859cc9 8 * WARRANTY of ANY KIND is provided. This heading must NOT be removed from
rgrover1 103:138bdc859cc9 9 * the file.
rgrover1 103:138bdc859cc9 10 *
rgrover1 103:138bdc859cc9 11 */
rgrover1 103:138bdc859cc9 12
rgrover1 103:138bdc859cc9 13 #include "ble_advdata.h"
rgrover1 103:138bdc859cc9 14 #include "nordic_common.h"
rgrover1 103:138bdc859cc9 15 #include "nrf_error.h"
rgrover1 103:138bdc859cc9 16 #include "ble_gap.h"
rgrover1 103:138bdc859cc9 17 #include "ble_srv_common.h"
rgrover1 103:138bdc859cc9 18 #include "app_util.h"
rgrover1 103:138bdc859cc9 19
rgrover1 103:138bdc859cc9 20
rgrover1 103:138bdc859cc9 21 // Offset from where advertisement data other than flags information can start.
rgrover1 103:138bdc859cc9 22 #define ADV_FLAG_OFFSET 2
rgrover1 103:138bdc859cc9 23
rgrover1 103:138bdc859cc9 24 // Offset for Advertising Data.
rgrover1 103:138bdc859cc9 25 // Offset is 2 as each Advertising Data contain 1 octet of Adveritising Data Type and
rgrover1 103:138bdc859cc9 26 // one octet Advertising Data Length.
rgrover1 103:138bdc859cc9 27 #define ADV_DATA_OFFSET 2
rgrover1 103:138bdc859cc9 28
rgrover1 103:138bdc859cc9 29 // NOTE: For now, Security Manager TK Value and Security Manager Out of Band Flags (OOB) are omitted
rgrover1 103:138bdc859cc9 30 // from the advertising data.
rgrover1 103:138bdc859cc9 31
rgrover1 103:138bdc859cc9 32
rgrover1 103:138bdc859cc9 33 static uint32_t name_encode(const ble_advdata_t * p_advdata,
rgrover1 103:138bdc859cc9 34 uint8_t * p_encoded_data,
rgrover1 103:138bdc859cc9 35 uint8_t * p_len)
rgrover1 103:138bdc859cc9 36 {
rgrover1 103:138bdc859cc9 37 uint32_t err_code;
rgrover1 103:138bdc859cc9 38 uint16_t rem_adv_data_len;
rgrover1 103:138bdc859cc9 39 uint16_t actual_length;
rgrover1 103:138bdc859cc9 40 uint8_t adv_data_format;
rgrover1 103:138bdc859cc9 41 uint8_t adv_offset;
rgrover1 103:138bdc859cc9 42
rgrover1 103:138bdc859cc9 43 adv_offset = *p_len;
rgrover1 103:138bdc859cc9 44
rgrover1 103:138bdc859cc9 45
rgrover1 103:138bdc859cc9 46 // Check for buffer overflow.
rgrover1 103:138bdc859cc9 47 if ((adv_offset + ADV_DATA_OFFSET > BLE_GAP_ADV_MAX_SIZE) ||
rgrover1 103:138bdc859cc9 48 ((p_advdata->short_name_len + ADV_DATA_OFFSET) > BLE_GAP_ADV_MAX_SIZE))
rgrover1 103:138bdc859cc9 49 {
rgrover1 103:138bdc859cc9 50 return NRF_ERROR_DATA_SIZE;
rgrover1 103:138bdc859cc9 51 }
rgrover1 103:138bdc859cc9 52 actual_length = rem_adv_data_len = (BLE_GAP_ADV_MAX_SIZE - adv_offset - ADV_FLAG_OFFSET);
rgrover1 103:138bdc859cc9 53
rgrover1 103:138bdc859cc9 54 // Get GAP device name and length
rgrover1 103:138bdc859cc9 55 err_code = sd_ble_gap_device_name_get(&p_encoded_data[adv_offset + ADV_DATA_OFFSET],
rgrover1 103:138bdc859cc9 56 &actual_length);
rgrover1 103:138bdc859cc9 57 if (err_code != NRF_SUCCESS)
rgrover1 103:138bdc859cc9 58 {
rgrover1 103:138bdc859cc9 59 return err_code;
rgrover1 103:138bdc859cc9 60 }
rgrover1 103:138bdc859cc9 61
rgrover1 103:138bdc859cc9 62 // Check if device internd to use short name and it can fit available data size.
rgrover1 103:138bdc859cc9 63 if ((p_advdata->name_type == BLE_ADVDATA_FULL_NAME) && (actual_length <= rem_adv_data_len))
rgrover1 103:138bdc859cc9 64 {
rgrover1 103:138bdc859cc9 65 // Complete device name can fit, setting Complete Name in Adv Data.
rgrover1 103:138bdc859cc9 66 adv_data_format = BLE_GAP_AD_TYPE_COMPLETE_LOCAL_NAME;
rgrover1 103:138bdc859cc9 67 rem_adv_data_len = actual_length;
rgrover1 103:138bdc859cc9 68 }
rgrover1 103:138bdc859cc9 69 else
rgrover1 103:138bdc859cc9 70 {
rgrover1 103:138bdc859cc9 71 // Else short name needs to be used. Or application has requested use of short name.
rgrover1 103:138bdc859cc9 72 adv_data_format = BLE_GAP_AD_TYPE_SHORT_LOCAL_NAME;
rgrover1 103:138bdc859cc9 73
rgrover1 103:138bdc859cc9 74 // If application has set a preference on the short name size, it needs to be considered,
rgrover1 103:138bdc859cc9 75 // else fit what can be fit.
rgrover1 103:138bdc859cc9 76 if ((p_advdata->short_name_len != 0) && (p_advdata->short_name_len <= rem_adv_data_len))
rgrover1 103:138bdc859cc9 77 {
rgrover1 103:138bdc859cc9 78 // Short name fits available size.
rgrover1 103:138bdc859cc9 79 rem_adv_data_len = p_advdata->short_name_len;
rgrover1 103:138bdc859cc9 80 }
rgrover1 103:138bdc859cc9 81 // Else whatever can fit the data buffer will be packed.
rgrover1 103:138bdc859cc9 82 else
rgrover1 103:138bdc859cc9 83 {
rgrover1 103:138bdc859cc9 84 rem_adv_data_len = actual_length;
rgrover1 103:138bdc859cc9 85 }
rgrover1 103:138bdc859cc9 86 }
rgrover1 103:138bdc859cc9 87
rgrover1 103:138bdc859cc9 88 // Complete name field in encoded data.
rgrover1 103:138bdc859cc9 89 p_encoded_data[adv_offset++] = rem_adv_data_len + 1;
rgrover1 103:138bdc859cc9 90 p_encoded_data[adv_offset++] = adv_data_format;
rgrover1 103:138bdc859cc9 91 (*p_len) += (rem_adv_data_len + ADV_DATA_OFFSET);
rgrover1 103:138bdc859cc9 92
rgrover1 103:138bdc859cc9 93 return NRF_SUCCESS;
rgrover1 103:138bdc859cc9 94 }
rgrover1 103:138bdc859cc9 95
rgrover1 103:138bdc859cc9 96
rgrover1 103:138bdc859cc9 97 static uint32_t appearance_encode(uint8_t * p_encoded_data, uint8_t * p_len)
rgrover1 103:138bdc859cc9 98 {
rgrover1 103:138bdc859cc9 99 uint32_t err_code;
rgrover1 103:138bdc859cc9 100 uint16_t appearance;
rgrover1 103:138bdc859cc9 101
rgrover1 103:138bdc859cc9 102 // Check for buffer overflow.
rgrover1 103:138bdc859cc9 103 if ((*p_len) + 4 > BLE_GAP_ADV_MAX_SIZE)
rgrover1 103:138bdc859cc9 104 {
rgrover1 103:138bdc859cc9 105 return NRF_ERROR_DATA_SIZE;
rgrover1 103:138bdc859cc9 106 }
rgrover1 103:138bdc859cc9 107
rgrover1 103:138bdc859cc9 108 // Get GAP appearance field.
rgrover1 103:138bdc859cc9 109 err_code = sd_ble_gap_appearance_get(&appearance);
rgrover1 103:138bdc859cc9 110 if (err_code != NRF_SUCCESS)
rgrover1 103:138bdc859cc9 111 {
rgrover1 103:138bdc859cc9 112 return err_code;
rgrover1 103:138bdc859cc9 113 }
rgrover1 103:138bdc859cc9 114
rgrover1 103:138bdc859cc9 115 // Encode Length, AD Type and Appearance.
rgrover1 103:138bdc859cc9 116 p_encoded_data[(*p_len)++] = 3;
rgrover1 103:138bdc859cc9 117 p_encoded_data[(*p_len)++] = BLE_GAP_AD_TYPE_APPEARANCE;
rgrover1 103:138bdc859cc9 118
rgrover1 103:138bdc859cc9 119 (*p_len) += uint16_encode(appearance, &p_encoded_data[*p_len]);
rgrover1 103:138bdc859cc9 120
rgrover1 103:138bdc859cc9 121 return NRF_SUCCESS;
rgrover1 103:138bdc859cc9 122 }
rgrover1 103:138bdc859cc9 123
rgrover1 103:138bdc859cc9 124
rgrover1 103:138bdc859cc9 125 static uint32_t tx_power_level_encode(int8_t tx_power_level,
rgrover1 103:138bdc859cc9 126 uint8_t * p_encoded_data,
rgrover1 103:138bdc859cc9 127 uint8_t * p_len)
rgrover1 103:138bdc859cc9 128 {
rgrover1 103:138bdc859cc9 129 // Check for buffer overflow.
rgrover1 103:138bdc859cc9 130 if ((*p_len) + 3 > BLE_GAP_ADV_MAX_SIZE)
rgrover1 103:138bdc859cc9 131 {
rgrover1 103:138bdc859cc9 132 return NRF_ERROR_DATA_SIZE;
rgrover1 103:138bdc859cc9 133 }
rgrover1 103:138bdc859cc9 134
rgrover1 103:138bdc859cc9 135 // Encode TX Power Level.
rgrover1 103:138bdc859cc9 136 p_encoded_data[(*p_len)++] = 2;
rgrover1 103:138bdc859cc9 137 p_encoded_data[(*p_len)++] = BLE_GAP_AD_TYPE_TX_POWER_LEVEL;
rgrover1 103:138bdc859cc9 138 p_encoded_data[(*p_len)++] = (uint8_t)tx_power_level;
rgrover1 103:138bdc859cc9 139
rgrover1 103:138bdc859cc9 140 return NRF_SUCCESS;
rgrover1 103:138bdc859cc9 141 }
rgrover1 103:138bdc859cc9 142
rgrover1 103:138bdc859cc9 143
rgrover1 103:138bdc859cc9 144 static uint32_t uuid_list_sized_encode(const ble_advdata_uuid_list_t * p_uuid_list,
rgrover1 103:138bdc859cc9 145 uint8_t adv_type,
rgrover1 103:138bdc859cc9 146 uint8_t uuid_size,
rgrover1 103:138bdc859cc9 147 uint8_t * p_encoded_data,
rgrover1 103:138bdc859cc9 148 uint8_t * p_len)
rgrover1 103:138bdc859cc9 149 {
rgrover1 103:138bdc859cc9 150 int i;
rgrover1 103:138bdc859cc9 151 bool is_heading_written = false;
rgrover1 103:138bdc859cc9 152 uint8_t start_pos = *p_len;
rgrover1 103:138bdc859cc9 153
rgrover1 103:138bdc859cc9 154 for (i = 0; i < p_uuid_list->uuid_cnt; i++)
rgrover1 103:138bdc859cc9 155 {
rgrover1 103:138bdc859cc9 156 uint32_t err_code;
rgrover1 103:138bdc859cc9 157 uint8_t encoded_size;
rgrover1 103:138bdc859cc9 158 ble_uuid_t uuid = p_uuid_list->p_uuids[i];
rgrover1 103:138bdc859cc9 159
rgrover1 103:138bdc859cc9 160 // Find encoded uuid size.
rgrover1 103:138bdc859cc9 161 err_code = sd_ble_uuid_encode(&uuid, &encoded_size, NULL);
rgrover1 103:138bdc859cc9 162 if (err_code != NRF_SUCCESS)
rgrover1 103:138bdc859cc9 163 {
rgrover1 103:138bdc859cc9 164 return err_code;
rgrover1 103:138bdc859cc9 165 }
rgrover1 103:138bdc859cc9 166
rgrover1 103:138bdc859cc9 167 // Check size.
rgrover1 103:138bdc859cc9 168 if (encoded_size == uuid_size)
rgrover1 103:138bdc859cc9 169 {
rgrover1 103:138bdc859cc9 170 uint8_t heading_bytes = (is_heading_written) ? 0 : 2;
rgrover1 103:138bdc859cc9 171
rgrover1 103:138bdc859cc9 172 // Check for buffer overflow
rgrover1 103:138bdc859cc9 173 if (*p_len + encoded_size + heading_bytes > BLE_GAP_ADV_MAX_SIZE)
rgrover1 103:138bdc859cc9 174 {
rgrover1 103:138bdc859cc9 175 return NRF_ERROR_DATA_SIZE;
rgrover1 103:138bdc859cc9 176 }
rgrover1 103:138bdc859cc9 177
rgrover1 103:138bdc859cc9 178 if (!is_heading_written)
rgrover1 103:138bdc859cc9 179 {
rgrover1 103:138bdc859cc9 180 // Write AD structure heading.
rgrover1 103:138bdc859cc9 181 (*p_len)++;
rgrover1 103:138bdc859cc9 182 p_encoded_data[(*p_len)++] = adv_type;
rgrover1 103:138bdc859cc9 183 is_heading_written = true;
rgrover1 103:138bdc859cc9 184 }
rgrover1 103:138bdc859cc9 185
rgrover1 103:138bdc859cc9 186 // Write UUID.
rgrover1 103:138bdc859cc9 187 err_code = sd_ble_uuid_encode(&uuid, &encoded_size, &p_encoded_data[*p_len]);
rgrover1 103:138bdc859cc9 188 if (err_code != NRF_SUCCESS)
rgrover1 103:138bdc859cc9 189 {
rgrover1 103:138bdc859cc9 190 return err_code;
rgrover1 103:138bdc859cc9 191 }
rgrover1 103:138bdc859cc9 192 (*p_len) += encoded_size;
rgrover1 103:138bdc859cc9 193 }
rgrover1 103:138bdc859cc9 194 }
rgrover1 103:138bdc859cc9 195
rgrover1 103:138bdc859cc9 196 if (is_heading_written)
rgrover1 103:138bdc859cc9 197 {
rgrover1 103:138bdc859cc9 198 // Write length.
rgrover1 103:138bdc859cc9 199 p_encoded_data[start_pos] = (*p_len) - (start_pos + 1);
rgrover1 103:138bdc859cc9 200 }
rgrover1 103:138bdc859cc9 201
rgrover1 103:138bdc859cc9 202 return NRF_SUCCESS;
rgrover1 103:138bdc859cc9 203 }
rgrover1 103:138bdc859cc9 204
rgrover1 103:138bdc859cc9 205
rgrover1 103:138bdc859cc9 206 static uint32_t uuid_list_encode(const ble_advdata_uuid_list_t * p_uuid_list,
rgrover1 103:138bdc859cc9 207 uint8_t adv_type_16,
rgrover1 103:138bdc859cc9 208 uint8_t adv_type_128,
rgrover1 103:138bdc859cc9 209 uint8_t * p_encoded_data,
rgrover1 103:138bdc859cc9 210 uint8_t * p_len)
rgrover1 103:138bdc859cc9 211 {
rgrover1 103:138bdc859cc9 212 uint32_t err_code;
rgrover1 103:138bdc859cc9 213
rgrover1 103:138bdc859cc9 214 // Encode 16 bit UUIDs.
rgrover1 103:138bdc859cc9 215 err_code = uuid_list_sized_encode(p_uuid_list,
rgrover1 103:138bdc859cc9 216 adv_type_16,
rgrover1 103:138bdc859cc9 217 sizeof(uint16_le_t),
rgrover1 103:138bdc859cc9 218 p_encoded_data,
rgrover1 103:138bdc859cc9 219 p_len);
rgrover1 103:138bdc859cc9 220 if (err_code != NRF_SUCCESS)
rgrover1 103:138bdc859cc9 221 {
rgrover1 103:138bdc859cc9 222 return err_code;
rgrover1 103:138bdc859cc9 223 }
rgrover1 103:138bdc859cc9 224
rgrover1 103:138bdc859cc9 225 // Encode 128 bit UUIDs.
rgrover1 103:138bdc859cc9 226 err_code = uuid_list_sized_encode(p_uuid_list,
rgrover1 103:138bdc859cc9 227 adv_type_128,
rgrover1 103:138bdc859cc9 228 sizeof(ble_uuid128_t),
rgrover1 103:138bdc859cc9 229 p_encoded_data,
rgrover1 103:138bdc859cc9 230 p_len);
rgrover1 103:138bdc859cc9 231 if (err_code != NRF_SUCCESS)
rgrover1 103:138bdc859cc9 232 {
rgrover1 103:138bdc859cc9 233 return err_code;
rgrover1 103:138bdc859cc9 234 }
rgrover1 103:138bdc859cc9 235
rgrover1 103:138bdc859cc9 236 return NRF_SUCCESS;
rgrover1 103:138bdc859cc9 237 }
rgrover1 103:138bdc859cc9 238
rgrover1 103:138bdc859cc9 239
rgrover1 103:138bdc859cc9 240 static uint32_t conn_int_check(const ble_advdata_conn_int_t *p_conn_int)
rgrover1 103:138bdc859cc9 241 {
rgrover1 103:138bdc859cc9 242 // Check Minimum Connection Interval.
rgrover1 103:138bdc859cc9 243 if ((p_conn_int->min_conn_interval < 0x0006) ||
rgrover1 103:138bdc859cc9 244 (
rgrover1 103:138bdc859cc9 245 (p_conn_int->min_conn_interval > 0x0c80) &&
rgrover1 103:138bdc859cc9 246 (p_conn_int->min_conn_interval != 0xffff)
rgrover1 103:138bdc859cc9 247 )
rgrover1 103:138bdc859cc9 248 )
rgrover1 103:138bdc859cc9 249 {
rgrover1 103:138bdc859cc9 250 return NRF_ERROR_INVALID_PARAM;
rgrover1 103:138bdc859cc9 251 }
rgrover1 103:138bdc859cc9 252
rgrover1 103:138bdc859cc9 253 // Check Maximum Connection Interval.
rgrover1 103:138bdc859cc9 254 if ((p_conn_int->max_conn_interval < 0x0006) ||
rgrover1 103:138bdc859cc9 255 (
rgrover1 103:138bdc859cc9 256 (p_conn_int->max_conn_interval > 0x0c80) &&
rgrover1 103:138bdc859cc9 257 (p_conn_int->max_conn_interval != 0xffff)
rgrover1 103:138bdc859cc9 258 )
rgrover1 103:138bdc859cc9 259 )
rgrover1 103:138bdc859cc9 260 {
rgrover1 103:138bdc859cc9 261 return NRF_ERROR_INVALID_PARAM;
rgrover1 103:138bdc859cc9 262 }
rgrover1 103:138bdc859cc9 263
rgrover1 103:138bdc859cc9 264 // Make sure Minimum Connection Interval is not bigger than Maximum Connection Interval.
rgrover1 103:138bdc859cc9 265 if ((p_conn_int->min_conn_interval != 0xffff) &&
rgrover1 103:138bdc859cc9 266 (p_conn_int->max_conn_interval != 0xffff) &&
rgrover1 103:138bdc859cc9 267 (p_conn_int->min_conn_interval > p_conn_int->max_conn_interval)
rgrover1 103:138bdc859cc9 268 )
rgrover1 103:138bdc859cc9 269 {
rgrover1 103:138bdc859cc9 270 return NRF_ERROR_INVALID_PARAM;
rgrover1 103:138bdc859cc9 271 }
rgrover1 103:138bdc859cc9 272
rgrover1 103:138bdc859cc9 273 return NRF_SUCCESS;
rgrover1 103:138bdc859cc9 274 }
rgrover1 103:138bdc859cc9 275
rgrover1 103:138bdc859cc9 276
rgrover1 103:138bdc859cc9 277 static uint32_t conn_int_encode(const ble_advdata_conn_int_t * p_conn_int,
rgrover1 103:138bdc859cc9 278 uint8_t * p_encoded_data,
rgrover1 103:138bdc859cc9 279 uint8_t * p_len)
rgrover1 103:138bdc859cc9 280 {
rgrover1 103:138bdc859cc9 281 uint32_t err_code;
rgrover1 103:138bdc859cc9 282
rgrover1 103:138bdc859cc9 283 // Check for buffer overflow.
rgrover1 103:138bdc859cc9 284 if ((*p_len) + ADV_DATA_OFFSET + 2 * sizeof(uint16_le_t) > BLE_GAP_ADV_MAX_SIZE)
rgrover1 103:138bdc859cc9 285 {
rgrover1 103:138bdc859cc9 286 return NRF_ERROR_DATA_SIZE;
rgrover1 103:138bdc859cc9 287 }
rgrover1 103:138bdc859cc9 288
rgrover1 103:138bdc859cc9 289 // Check parameters.
rgrover1 103:138bdc859cc9 290 err_code = conn_int_check(p_conn_int);
rgrover1 103:138bdc859cc9 291 if (err_code != NRF_SUCCESS)
rgrover1 103:138bdc859cc9 292 {
rgrover1 103:138bdc859cc9 293 return err_code;
rgrover1 103:138bdc859cc9 294 }
rgrover1 103:138bdc859cc9 295
rgrover1 103:138bdc859cc9 296 // Encode Length and AD Type.
rgrover1 103:138bdc859cc9 297 p_encoded_data[(*p_len)++] = 1 + 2 * sizeof(uint16_le_t);
rgrover1 103:138bdc859cc9 298 p_encoded_data[(*p_len)++] = BLE_GAP_AD_TYPE_SLAVE_CONNECTION_INTERVAL_RANGE;
rgrover1 103:138bdc859cc9 299
rgrover1 103:138bdc859cc9 300 // Encode Minimum and Maximum Connection Intervals.
rgrover1 103:138bdc859cc9 301 (*p_len) += uint16_encode(p_conn_int->min_conn_interval, &p_encoded_data[*p_len]);
rgrover1 103:138bdc859cc9 302 (*p_len) += uint16_encode(p_conn_int->max_conn_interval, &p_encoded_data[*p_len]);
rgrover1 103:138bdc859cc9 303
rgrover1 103:138bdc859cc9 304 return NRF_SUCCESS;
rgrover1 103:138bdc859cc9 305 }
rgrover1 103:138bdc859cc9 306
rgrover1 103:138bdc859cc9 307
rgrover1 103:138bdc859cc9 308 static uint32_t manuf_specific_data_encode(const ble_advdata_manuf_data_t * p_manuf_sp_data,
rgrover1 103:138bdc859cc9 309 uint8_t * p_encoded_data,
rgrover1 103:138bdc859cc9 310 uint8_t * p_len)
rgrover1 103:138bdc859cc9 311 {
rgrover1 103:138bdc859cc9 312 uint8_t data_size = sizeof(uint16_le_t) + p_manuf_sp_data->data.size;
rgrover1 103:138bdc859cc9 313
rgrover1 103:138bdc859cc9 314 // Check for buffer overflow.
rgrover1 103:138bdc859cc9 315 if ((*p_len) + ADV_DATA_OFFSET + data_size > BLE_GAP_ADV_MAX_SIZE)
rgrover1 103:138bdc859cc9 316 {
rgrover1 103:138bdc859cc9 317 return NRF_ERROR_DATA_SIZE;
rgrover1 103:138bdc859cc9 318 }
rgrover1 103:138bdc859cc9 319
rgrover1 103:138bdc859cc9 320 // Encode Length and AD Type.
rgrover1 103:138bdc859cc9 321 p_encoded_data[(*p_len)++] = 1 + data_size;
rgrover1 103:138bdc859cc9 322 p_encoded_data[(*p_len)++] = BLE_GAP_AD_TYPE_MANUFACTURER_SPECIFIC_DATA;
rgrover1 103:138bdc859cc9 323
rgrover1 103:138bdc859cc9 324 // Encode Company Identifier.
rgrover1 103:138bdc859cc9 325 (*p_len) += uint16_encode(p_manuf_sp_data->company_identifier, &p_encoded_data[*p_len]);
rgrover1 103:138bdc859cc9 326
rgrover1 103:138bdc859cc9 327 // Encode additional manufacturer specific data.
rgrover1 103:138bdc859cc9 328 if (p_manuf_sp_data->data.size > 0)
rgrover1 103:138bdc859cc9 329 {
rgrover1 103:138bdc859cc9 330 if (p_manuf_sp_data->data.p_data == NULL)
rgrover1 103:138bdc859cc9 331 {
rgrover1 103:138bdc859cc9 332 return NRF_ERROR_INVALID_PARAM;
rgrover1 103:138bdc859cc9 333 }
rgrover1 103:138bdc859cc9 334 memcpy(&p_encoded_data[*p_len], p_manuf_sp_data->data.p_data, p_manuf_sp_data->data.size);
rgrover1 103:138bdc859cc9 335 (*p_len) += p_manuf_sp_data->data.size;
rgrover1 103:138bdc859cc9 336 }
rgrover1 103:138bdc859cc9 337
rgrover1 103:138bdc859cc9 338 return NRF_SUCCESS;
rgrover1 103:138bdc859cc9 339 }
rgrover1 103:138bdc859cc9 340
rgrover1 103:138bdc859cc9 341
rgrover1 103:138bdc859cc9 342 static uint32_t service_data_encode(const ble_advdata_t * p_advdata,
rgrover1 103:138bdc859cc9 343 uint8_t * p_encoded_data,
rgrover1 103:138bdc859cc9 344 uint8_t * p_len)
rgrover1 103:138bdc859cc9 345 {
rgrover1 103:138bdc859cc9 346 uint8_t i;
rgrover1 103:138bdc859cc9 347
rgrover1 103:138bdc859cc9 348 // Check parameter consistency.
rgrover1 103:138bdc859cc9 349 if (p_advdata->p_service_data_array == NULL)
rgrover1 103:138bdc859cc9 350 {
rgrover1 103:138bdc859cc9 351 return NRF_ERROR_INVALID_PARAM;
rgrover1 103:138bdc859cc9 352 }
rgrover1 103:138bdc859cc9 353
rgrover1 103:138bdc859cc9 354 for (i = 0; i < p_advdata->service_data_count; i++)
rgrover1 103:138bdc859cc9 355 {
rgrover1 103:138bdc859cc9 356 ble_advdata_service_data_t * p_service_data;
rgrover1 103:138bdc859cc9 357 uint8_t data_size;
rgrover1 103:138bdc859cc9 358
rgrover1 103:138bdc859cc9 359 p_service_data = &p_advdata->p_service_data_array[i];
rgrover1 103:138bdc859cc9 360 data_size = sizeof(uint16_le_t) + p_service_data->data.size;
rgrover1 103:138bdc859cc9 361
rgrover1 103:138bdc859cc9 362 // Encode Length and AD Type.
rgrover1 103:138bdc859cc9 363 p_encoded_data[(*p_len)++] = 1 + data_size;
rgrover1 103:138bdc859cc9 364 p_encoded_data[(*p_len)++] = BLE_GAP_AD_TYPE_SERVICE_DATA;
rgrover1 103:138bdc859cc9 365
rgrover1 103:138bdc859cc9 366 // Encode service UUID.
rgrover1 103:138bdc859cc9 367 (*p_len) += uint16_encode(p_service_data->service_uuid, &p_encoded_data[*p_len]);
rgrover1 103:138bdc859cc9 368
rgrover1 103:138bdc859cc9 369 // Encode additional service data.
rgrover1 103:138bdc859cc9 370 if (p_service_data->data.size > 0)
rgrover1 103:138bdc859cc9 371 {
rgrover1 103:138bdc859cc9 372 if (p_service_data->data.p_data == NULL)
rgrover1 103:138bdc859cc9 373 {
rgrover1 103:138bdc859cc9 374 return NRF_ERROR_INVALID_PARAM;
rgrover1 103:138bdc859cc9 375 }
rgrover1 103:138bdc859cc9 376 memcpy(&p_encoded_data[*p_len], p_service_data->data.p_data, p_service_data->data.size);
rgrover1 103:138bdc859cc9 377 (*p_len) += p_service_data->data.size;
rgrover1 103:138bdc859cc9 378 }
rgrover1 103:138bdc859cc9 379 }
rgrover1 103:138bdc859cc9 380
rgrover1 103:138bdc859cc9 381 return NRF_SUCCESS;
rgrover1 103:138bdc859cc9 382 }
rgrover1 103:138bdc859cc9 383
rgrover1 103:138bdc859cc9 384
rgrover1 103:138bdc859cc9 385 static uint32_t adv_data_encode(const ble_advdata_t * p_advdata,
rgrover1 103:138bdc859cc9 386 uint8_t * p_encoded_data,
rgrover1 103:138bdc859cc9 387 uint8_t * p_len)
rgrover1 103:138bdc859cc9 388 {
rgrover1 103:138bdc859cc9 389 uint32_t err_code = NRF_SUCCESS;
rgrover1 103:138bdc859cc9 390
rgrover1 103:138bdc859cc9 391 *p_len = 0;
rgrover1 103:138bdc859cc9 392
rgrover1 103:138bdc859cc9 393 // Encode name.
rgrover1 103:138bdc859cc9 394 if (p_advdata->name_type != BLE_ADVDATA_NO_NAME)
rgrover1 103:138bdc859cc9 395 {
rgrover1 103:138bdc859cc9 396 err_code = name_encode(p_advdata, p_encoded_data, p_len);
rgrover1 103:138bdc859cc9 397 if (err_code != NRF_SUCCESS)
rgrover1 103:138bdc859cc9 398 {
rgrover1 103:138bdc859cc9 399 return err_code;
rgrover1 103:138bdc859cc9 400 }
rgrover1 103:138bdc859cc9 401 }
rgrover1 103:138bdc859cc9 402
rgrover1 103:138bdc859cc9 403 // Encode appearance.
rgrover1 103:138bdc859cc9 404 if (p_advdata->include_appearance)
rgrover1 103:138bdc859cc9 405 {
rgrover1 103:138bdc859cc9 406 err_code = appearance_encode(p_encoded_data, p_len);
rgrover1 103:138bdc859cc9 407 if (err_code != NRF_SUCCESS)
rgrover1 103:138bdc859cc9 408 {
rgrover1 103:138bdc859cc9 409 return err_code;
rgrover1 103:138bdc859cc9 410 }
rgrover1 103:138bdc859cc9 411 }
rgrover1 103:138bdc859cc9 412
rgrover1 112:737b08b3b995 413 if(p_advdata->flags != 0 )
rgrover1 103:138bdc859cc9 414 {
rgrover1 112:737b08b3b995 415 // Encode flags.
rgrover1 112:737b08b3b995 416 p_encoded_data[(*p_len)++] = 1 + sizeof(uint8_t);
rgrover1 112:737b08b3b995 417 p_encoded_data[(*p_len)++] = BLE_GAP_AD_TYPE_FLAGS;
rgrover1 112:737b08b3b995 418 p_encoded_data[(*p_len)++] = p_advdata->flags;
rgrover1 112:737b08b3b995 419 }
rgrover1 103:138bdc859cc9 420
rgrover1 103:138bdc859cc9 421 // Encode TX power level.
rgrover1 103:138bdc859cc9 422 if (p_advdata->p_tx_power_level != NULL)
rgrover1 103:138bdc859cc9 423 {
rgrover1 103:138bdc859cc9 424 err_code = tx_power_level_encode(*p_advdata->p_tx_power_level, p_encoded_data, p_len);
rgrover1 103:138bdc859cc9 425 if (err_code != NRF_SUCCESS)
rgrover1 103:138bdc859cc9 426 {
rgrover1 103:138bdc859cc9 427 return err_code;
rgrover1 103:138bdc859cc9 428 }
rgrover1 103:138bdc859cc9 429 }
rgrover1 103:138bdc859cc9 430
rgrover1 103:138bdc859cc9 431 // Encode 'more available' uuid list.
rgrover1 103:138bdc859cc9 432 if (p_advdata->uuids_more_available.uuid_cnt > 0)
rgrover1 103:138bdc859cc9 433 {
rgrover1 103:138bdc859cc9 434 err_code = uuid_list_encode(&p_advdata->uuids_more_available,
rgrover1 103:138bdc859cc9 435 BLE_GAP_AD_TYPE_16BIT_SERVICE_UUID_MORE_AVAILABLE,
rgrover1 103:138bdc859cc9 436 BLE_GAP_AD_TYPE_128BIT_SERVICE_UUID_MORE_AVAILABLE,
rgrover1 103:138bdc859cc9 437 p_encoded_data,
rgrover1 103:138bdc859cc9 438 p_len);
rgrover1 103:138bdc859cc9 439 if (err_code != NRF_SUCCESS)
rgrover1 103:138bdc859cc9 440 {
rgrover1 103:138bdc859cc9 441 return err_code;
rgrover1 103:138bdc859cc9 442 }
rgrover1 103:138bdc859cc9 443 }
rgrover1 103:138bdc859cc9 444
rgrover1 103:138bdc859cc9 445 // Encode 'complete' uuid list.
rgrover1 103:138bdc859cc9 446 if (p_advdata->uuids_complete.uuid_cnt > 0)
rgrover1 103:138bdc859cc9 447 {
rgrover1 103:138bdc859cc9 448 err_code = uuid_list_encode(&p_advdata->uuids_complete,
rgrover1 103:138bdc859cc9 449 BLE_GAP_AD_TYPE_16BIT_SERVICE_UUID_COMPLETE,
rgrover1 103:138bdc859cc9 450 BLE_GAP_AD_TYPE_128BIT_SERVICE_UUID_COMPLETE,
rgrover1 103:138bdc859cc9 451 p_encoded_data,
rgrover1 103:138bdc859cc9 452 p_len);
rgrover1 103:138bdc859cc9 453 if (err_code != NRF_SUCCESS)
rgrover1 103:138bdc859cc9 454 {
rgrover1 103:138bdc859cc9 455 return err_code;
rgrover1 103:138bdc859cc9 456 }
rgrover1 103:138bdc859cc9 457 }
rgrover1 103:138bdc859cc9 458
rgrover1 103:138bdc859cc9 459 // Encode 'solicited service' uuid list.
rgrover1 103:138bdc859cc9 460 if (p_advdata->uuids_solicited.uuid_cnt > 0)
rgrover1 103:138bdc859cc9 461 {
rgrover1 103:138bdc859cc9 462 err_code = uuid_list_encode(&p_advdata->uuids_solicited,
rgrover1 103:138bdc859cc9 463 BLE_GAP_AD_TYPE_SOLICITED_SERVICE_UUIDS_16BIT,
rgrover1 103:138bdc859cc9 464 BLE_GAP_AD_TYPE_SOLICITED_SERVICE_UUIDS_128BIT,
rgrover1 103:138bdc859cc9 465 p_encoded_data,
rgrover1 103:138bdc859cc9 466 p_len);
rgrover1 103:138bdc859cc9 467 if (err_code != NRF_SUCCESS)
rgrover1 103:138bdc859cc9 468 {
rgrover1 103:138bdc859cc9 469 return err_code;
rgrover1 103:138bdc859cc9 470 }
rgrover1 103:138bdc859cc9 471 }
rgrover1 103:138bdc859cc9 472
rgrover1 103:138bdc859cc9 473 // Encode Slave Connection Interval Range.
rgrover1 103:138bdc859cc9 474 if (p_advdata->p_slave_conn_int != NULL)
rgrover1 103:138bdc859cc9 475 {
rgrover1 103:138bdc859cc9 476 err_code = conn_int_encode(p_advdata->p_slave_conn_int, p_encoded_data, p_len);
rgrover1 103:138bdc859cc9 477 if (err_code != NRF_SUCCESS)
rgrover1 103:138bdc859cc9 478 {
rgrover1 103:138bdc859cc9 479 return err_code;
rgrover1 103:138bdc859cc9 480 }
rgrover1 103:138bdc859cc9 481 }
rgrover1 103:138bdc859cc9 482
rgrover1 103:138bdc859cc9 483 // Encode Manufacturer Specific Data.
rgrover1 103:138bdc859cc9 484 if (p_advdata->p_manuf_specific_data != NULL)
rgrover1 103:138bdc859cc9 485 {
rgrover1 103:138bdc859cc9 486 err_code = manuf_specific_data_encode(p_advdata->p_manuf_specific_data,
rgrover1 103:138bdc859cc9 487 p_encoded_data,
rgrover1 103:138bdc859cc9 488 p_len);
rgrover1 103:138bdc859cc9 489 if (err_code != NRF_SUCCESS)
rgrover1 103:138bdc859cc9 490 {
rgrover1 103:138bdc859cc9 491 return err_code;
rgrover1 103:138bdc859cc9 492 }
rgrover1 103:138bdc859cc9 493 }
rgrover1 103:138bdc859cc9 494
rgrover1 103:138bdc859cc9 495 // Encode Service Data.
rgrover1 103:138bdc859cc9 496 if (p_advdata->service_data_count > 0)
rgrover1 103:138bdc859cc9 497 {
rgrover1 103:138bdc859cc9 498 err_code = service_data_encode(p_advdata, p_encoded_data, p_len);
rgrover1 103:138bdc859cc9 499 if (err_code != NRF_SUCCESS)
rgrover1 103:138bdc859cc9 500 {
rgrover1 103:138bdc859cc9 501 return err_code;
rgrover1 103:138bdc859cc9 502 }
rgrover1 103:138bdc859cc9 503 }
rgrover1 103:138bdc859cc9 504
rgrover1 103:138bdc859cc9 505 return err_code;
rgrover1 103:138bdc859cc9 506 }
rgrover1 103:138bdc859cc9 507
rgrover1 103:138bdc859cc9 508
rgrover1 103:138bdc859cc9 509 static uint32_t advdata_check(const ble_advdata_t * p_advdata)
rgrover1 103:138bdc859cc9 510 {
rgrover1 103:138bdc859cc9 511 // Flags must be included in advertising data, and the BLE_GAP_ADV_FLAG_BR_EDR_NOT_SUPPORTED flag must be set.
rgrover1 112:737b08b3b995 512 if (
rgrover1 112:737b08b3b995 513 ((p_advdata->flags & BLE_GAP_ADV_FLAG_BR_EDR_NOT_SUPPORTED) == 0)
rgrover1 103:138bdc859cc9 514 )
rgrover1 103:138bdc859cc9 515 {
rgrover1 103:138bdc859cc9 516 return NRF_ERROR_INVALID_PARAM;
rgrover1 103:138bdc859cc9 517 }
rgrover1 103:138bdc859cc9 518
rgrover1 103:138bdc859cc9 519 return NRF_SUCCESS;
rgrover1 103:138bdc859cc9 520 }
rgrover1 103:138bdc859cc9 521
rgrover1 103:138bdc859cc9 522
rgrover1 103:138bdc859cc9 523 static uint32_t srdata_check(const ble_advdata_t * p_srdata)
rgrover1 103:138bdc859cc9 524 {
rgrover1 103:138bdc859cc9 525 // Flags shall not be included in the scan response data.
rgrover1 112:737b08b3b995 526 if (p_srdata->flags)
rgrover1 103:138bdc859cc9 527 {
rgrover1 103:138bdc859cc9 528 return NRF_ERROR_INVALID_PARAM;
rgrover1 103:138bdc859cc9 529 }
rgrover1 103:138bdc859cc9 530
rgrover1 103:138bdc859cc9 531 return NRF_SUCCESS;
rgrover1 103:138bdc859cc9 532 }
rgrover1 103:138bdc859cc9 533
rgrover1 103:138bdc859cc9 534
rgrover1 103:138bdc859cc9 535 uint32_t ble_advdata_set(const ble_advdata_t * p_advdata, const ble_advdata_t * p_srdata)
rgrover1 103:138bdc859cc9 536 {
rgrover1 103:138bdc859cc9 537 uint32_t err_code;
rgrover1 103:138bdc859cc9 538 uint8_t len_advdata = 0;
rgrover1 103:138bdc859cc9 539 uint8_t len_srdata = 0;
rgrover1 103:138bdc859cc9 540 uint8_t encoded_advdata[BLE_GAP_ADV_MAX_SIZE];
rgrover1 103:138bdc859cc9 541 uint8_t encoded_srdata[BLE_GAP_ADV_MAX_SIZE];
rgrover1 103:138bdc859cc9 542 uint8_t * p_encoded_advdata;
rgrover1 103:138bdc859cc9 543 uint8_t * p_encoded_srdata;
rgrover1 103:138bdc859cc9 544
rgrover1 103:138bdc859cc9 545 // Encode advertising data (if supplied).
rgrover1 103:138bdc859cc9 546 if (p_advdata != NULL)
rgrover1 103:138bdc859cc9 547 {
rgrover1 103:138bdc859cc9 548 err_code = advdata_check(p_advdata);
rgrover1 103:138bdc859cc9 549 if (err_code != NRF_SUCCESS)
rgrover1 103:138bdc859cc9 550 {
rgrover1 103:138bdc859cc9 551 return err_code;
rgrover1 103:138bdc859cc9 552 }
rgrover1 103:138bdc859cc9 553
rgrover1 103:138bdc859cc9 554 err_code = adv_data_encode(p_advdata, encoded_advdata, &len_advdata);
rgrover1 103:138bdc859cc9 555 if (err_code != NRF_SUCCESS)
rgrover1 103:138bdc859cc9 556 {
rgrover1 103:138bdc859cc9 557 return err_code;
rgrover1 103:138bdc859cc9 558 }
rgrover1 103:138bdc859cc9 559 p_encoded_advdata = encoded_advdata;
rgrover1 103:138bdc859cc9 560 }
rgrover1 103:138bdc859cc9 561 else
rgrover1 103:138bdc859cc9 562 {
rgrover1 103:138bdc859cc9 563 p_encoded_advdata = NULL;
rgrover1 103:138bdc859cc9 564 }
rgrover1 103:138bdc859cc9 565
rgrover1 103:138bdc859cc9 566 // Encode scan response data (if supplied).
rgrover1 103:138bdc859cc9 567 if (p_srdata != NULL)
rgrover1 103:138bdc859cc9 568 {
rgrover1 103:138bdc859cc9 569 err_code = srdata_check(p_srdata);
rgrover1 103:138bdc859cc9 570 if (err_code != NRF_SUCCESS)
rgrover1 103:138bdc859cc9 571 {
rgrover1 103:138bdc859cc9 572 return err_code;
rgrover1 103:138bdc859cc9 573 }
rgrover1 103:138bdc859cc9 574
rgrover1 103:138bdc859cc9 575 err_code = adv_data_encode(p_srdata, encoded_srdata, &len_srdata);
rgrover1 103:138bdc859cc9 576 if (err_code != NRF_SUCCESS)
rgrover1 103:138bdc859cc9 577 {
rgrover1 103:138bdc859cc9 578 return err_code;
rgrover1 103:138bdc859cc9 579 }
rgrover1 103:138bdc859cc9 580 p_encoded_srdata = encoded_srdata;
rgrover1 103:138bdc859cc9 581 }
rgrover1 103:138bdc859cc9 582 else
rgrover1 103:138bdc859cc9 583 {
rgrover1 103:138bdc859cc9 584 p_encoded_srdata = NULL;
rgrover1 103:138bdc859cc9 585 }
rgrover1 103:138bdc859cc9 586
rgrover1 103:138bdc859cc9 587 // Pass encoded advertising data and/or scan response data to the stack.
rgrover1 103:138bdc859cc9 588 return sd_ble_gap_adv_data_set(p_encoded_advdata, len_advdata, p_encoded_srdata, len_srdata);
rgrover1 103:138bdc859cc9 589 }