Cefn Hoile / nRF51822

Dependencies:   nrf51-sdk

Dependents:   microbit-dal

Fork of nRF51822 by Lancaster University

Committer:
rgrover1
Date:
Thu Jul 02 09:08:44 2015 +0100
Revision:
362:6fa0d4d555f6
Parent:
361:d2405f5a4853
Child:
370:295f76db798e
Synchronized with git rev 2716309c
Author: Rohit Grover
Release 0.4.0
=============

This is a major release which introduces the GATT Client functionality. It
aligns with release 0.4.0 of BLE_API.

Enhancements
~~~~~~~~~~~~

* Introduce GattClient. This includes functionality for service-discovery,
connections, and attribute-reads and writes. You'll find a demo program for
LEDBlinker on the mbed.org Bluetooth team page to use the new APIs. Some of
the GATT client functionality hasn't been implemented yet, but the APIs have
been added.

* We've added an implementation for the abstract base class for
SecurityManager. All security related APIs have been moved into that.

* There has been a major cleanup of APIs under BLE. APIs have now been
categorized as belonging to Gap, GattServer, GattClient, or SecurityManager.
There are accessors to get references for Gap, GattServer, GattClient, and
SecurityManager. A former call to ble.setAddress(...) is now expected to be
achieved with ble.gap().setAddress(...).

* We've cleaned up our APIs, and this has resulted in dropping some APIs like
BLE::reset().

* We've also dropped GattServer::initializeGattDatabase(). THis was added at
some point to support controllers where a commit point was needed to
indicate when the application had finished constructing the GATT database.
This API would get called internally before Gap::startAdvertising(). We now
expect the underlying port to do the equivalent of initializeGattDatabase()
implicitly upon Gap::startAdvertising().

* We've added a version of Gap::disconnect() which takes a connection handle.
The previous API (which did not take a connection handle) has been
deprecated; it will still work for situations where there's only a single
active connection. We hold on to that API to allow existing code to migrate
to the new API.

Bugfixes
~~~~~~~~

* None.

Who changed what in which revision?

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