Nordic stack and drivers for the mbed BLE API

Fork of nRF51822 by Nordic Semiconductor

Committer:
rgrover1
Date:
Wed Apr 15 08:59:24 2015 +0100
Revision:
109:425faebc8201
Parent:
97:e95e35845e1c
Child:
119:3ba3e377b972
Synchronized with git rev 2ebc6874
Author: Rohit Grover
Release 0.3.1
=============

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

* updating to v7.1 of the Nordic SDK. Re-organized file layout to match that from the SDK.

* Allow ble_conn_params to still use APP_TIMER if needed. Particularly in the case of the Bootloader.

This is made optional based on a preprocessor macro: USE_APP_TIMER. Some
Nordic code assumes the use of AppTimer, and if we replace it with mbed's
timer, then a lot more code gets pulled in than necessary. Ideally this
should not have been a problem, but it is, and the bootloader is a bit
unforgiving in its size constraints.

* Add new API: onRadioNotification(). Radio Notification is a feature that
enables ACTIVE and INACTIVE (nACTIVE) signals from the stack that notify the
application when the radio is in use. The ACTIVE signal is sent before the
Radio Event starts. The nACTIVE signal is sent at the end of the Radio
Event. These signals can be used by the application programmer to
synchronize application logic with radio activity. For example, the ACTIVE
signal can be used to shut off external devices to manage peak current drawn
during periods when the radio is on, or to trigger sensor data collection
for transmission in the Radio Event.

Bugfixes
~~~~~~~~

none.

Who changed what in which revision?

UserRevisionLine numberNew contents of line
Rohit Grover 22:c6ee8136847e 1 /* mbed Microcontroller Library
Rohit Grover 22:c6ee8136847e 2 * Copyright (c) 2006-2013 ARM Limited
Rohit Grover 22:c6ee8136847e 3 *
Rohit Grover 22:c6ee8136847e 4 * Licensed under the Apache License, Version 2.0 (the "License");
Rohit Grover 22:c6ee8136847e 5 * you may not use this file except in compliance with the License.
Rohit Grover 22:c6ee8136847e 6 * You may obtain a copy of the License at
Rohit Grover 22:c6ee8136847e 7 *
Rohit Grover 22:c6ee8136847e 8 * http://www.apache.org/licenses/LICENSE-2.0
Rohit Grover 22:c6ee8136847e 9 *
Rohit Grover 22:c6ee8136847e 10 * Unless required by applicable law or agreed to in writing, software
Rohit Grover 22:c6ee8136847e 11 * distributed under the License is distributed on an "AS IS" BASIS,
Rohit Grover 22:c6ee8136847e 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
Rohit Grover 22:c6ee8136847e 13 * See the License for the specific language governing permissions and
Rohit Grover 22:c6ee8136847e 14 * limitations under the License.
Rohit Grover 22:c6ee8136847e 15 */
Rohit Grover 22:c6ee8136847e 16
Rohit Grover 22:c6ee8136847e 17 #include "custom_helper.h"
Rohit Grover 22:c6ee8136847e 18
Rohit Grover 22:c6ee8136847e 19 /*
Rohit Grover 22:c6ee8136847e 20 * The current version of the soft-device doesn't handle duplicate 128-bit UUIDs
Rohit Grover 22:c6ee8136847e 21 * very well. It is therefore necessary to filter away duplicates before
Rohit Grover 22:c6ee8136847e 22 * passing long UUIDs to sd_ble_uuid_vs_add(). The following types and data
Rohit Grover 22:c6ee8136847e 23 * structures involved in maintaining a local cache of 128-bit UUIDs.
Rohit Grover 22:c6ee8136847e 24 */
Rohit Grover 22:c6ee8136847e 25 typedef struct {
Rohit Grover 56:a1071b629aa3 26 LongUUIDBytes_t uuid;
Rohit Grover 56:a1071b629aa3 27 uint8_t type;
Rohit Grover 22:c6ee8136847e 28 } converted_uuid_table_entry_t;
Rohit Grover 66:b3680699d9a4 29 static const unsigned UUID_TABLE_MAX_ENTRIES = 8; /* This is the maximum number of 128-bit UUIDs with distinct bases that
Rohit Grover 66:b3680699d9a4 30 * we expect to be in use; increase this limit if needed. */
Rohit Grover 22:c6ee8136847e 31 static unsigned uuidTableEntries = 0; /* current usage of the table */
Rohit Grover 22:c6ee8136847e 32 converted_uuid_table_entry_t convertedUUIDTable[UUID_TABLE_MAX_ENTRIES];
Rohit Grover 22:c6ee8136847e 33
Rohit Grover 22:c6ee8136847e 34 /**
Rohit Grover 22:c6ee8136847e 35 * lookup the cache of previously converted 128-bit UUIDs to find a type value.
Rohit Grover 66:b3680699d9a4 36 * @param uuid base 128-bit UUID
Rohit Grover 22:c6ee8136847e 37 * @param recoveredType the type field of the 3-byte nRF's uuid.
Rohit Grover 22:c6ee8136847e 38 * @return true if a match is found.
Rohit Grover 22:c6ee8136847e 39 */
Rohit Grover 22:c6ee8136847e 40 static bool
Rohit Grover 56:a1071b629aa3 41 lookupConvertedUUIDTable(const LongUUIDBytes_t uuid, uint8_t *recoveredType)
Rohit Grover 22:c6ee8136847e 42 {
Rohit Grover 22:c6ee8136847e 43 unsigned i;
Rohit Grover 22:c6ee8136847e 44 for (i = 0; i < uuidTableEntries; i++) {
rgrover1 97:e95e35845e1c 45 unsigned byteIndex;
rgrover1 97:e95e35845e1c 46 for (byteIndex = 0; byteIndex < LENGTH_OF_LONG_UUID; byteIndex++) {
rgrover1 97:e95e35845e1c 47 /* Skip bytes 2 and 3, because they contain the shortUUID (16-bit) version of the
rgrover1 97:e95e35845e1c 48 * long UUID; and we're comparing against the remainder. */
rgrover1 97:e95e35845e1c 49 if ((byteIndex == 2) || (byteIndex == 3)) {
rgrover1 97:e95e35845e1c 50 continue;
rgrover1 97:e95e35845e1c 51 }
rgrover1 97:e95e35845e1c 52
rgrover1 97:e95e35845e1c 53 if (convertedUUIDTable[i].uuid[byteIndex] != uuid[byteIndex]) {
rgrover1 97:e95e35845e1c 54 break;
rgrover1 97:e95e35845e1c 55 }
rgrover1 97:e95e35845e1c 56 }
rgrover1 97:e95e35845e1c 57
rgrover1 97:e95e35845e1c 58 if (byteIndex == LENGTH_OF_LONG_UUID) {
Rohit Grover 22:c6ee8136847e 59 *recoveredType = convertedUUIDTable[i].type;
Rohit Grover 22:c6ee8136847e 60 return true;
Rohit Grover 22:c6ee8136847e 61 }
Rohit Grover 22:c6ee8136847e 62 }
Rohit Grover 22:c6ee8136847e 63
Rohit Grover 22:c6ee8136847e 64 return false;
Rohit Grover 22:c6ee8136847e 65 }
Rohit Grover 22:c6ee8136847e 66
Rohit Grover 22:c6ee8136847e 67 static void
Rohit Grover 56:a1071b629aa3 68 addToConvertedUUIDTable(const LongUUIDBytes_t uuid, uint8_t type)
Rohit Grover 22:c6ee8136847e 69 {
Rohit Grover 22:c6ee8136847e 70 if (uuidTableEntries == UUID_TABLE_MAX_ENTRIES) {
Rohit Grover 66:b3680699d9a4 71 return; /* recovery needed; or at least the user should be warned about this fact.*/
Rohit Grover 22:c6ee8136847e 72 }
Rohit Grover 22:c6ee8136847e 73
rgrover1 97:e95e35845e1c 74 memcpy(convertedUUIDTable[uuidTableEntries].uuid, uuid, LENGTH_OF_LONG_UUID);
rgrover1 97:e95e35845e1c 75 convertedUUIDTable[uuidTableEntries].uuid[2] = 0;
rgrover1 97:e95e35845e1c 76 convertedUUIDTable[uuidTableEntries].uuid[3] = 0;
rgrover1 97:e95e35845e1c 77 convertedUUIDTable[uuidTableEntries].type = type;
Rohit Grover 22:c6ee8136847e 78 uuidTableEntries++;
Rohit Grover 22:c6ee8136847e 79 }
Rohit Grover 22:c6ee8136847e 80
Rohit Grover 22:c6ee8136847e 81 /**
Rohit Grover 22:c6ee8136847e 82 * The nRF transport has its own 3-byte representation of a UUID. If the user-
Rohit Grover 22:c6ee8136847e 83 * specified UUID is 128-bits wide, then the UUID base needs to be added to the
Rohit Grover 22:c6ee8136847e 84 * soft-device and converted to a 3-byte handle before being used further. This
Rohit Grover 22:c6ee8136847e 85 * function is responsible for this translation of user-specified UUIDs into
Rohit Grover 22:c6ee8136847e 86 * nRF's representation.
Rohit Grover 22:c6ee8136847e 87 *
Rohit Grover 22:c6ee8136847e 88 * @param[in] uuid
Rohit Grover 22:c6ee8136847e 89 * user-specified UUID
Rohit Grover 22:c6ee8136847e 90 * @return nRF
Rohit Grover 22:c6ee8136847e 91 * 3-byte UUID (containing a type and 16-bit UUID) representation
Rohit Grover 22:c6ee8136847e 92 * to be used with SVC calls.
Rohit Grover 22:c6ee8136847e 93 */
Rohit Grover 22:c6ee8136847e 94 ble_uuid_t custom_convert_to_nordic_uuid(const UUID &uuid)
Rohit Grover 22:c6ee8136847e 95 {
rgrover1 109:425faebc8201 96 ble_uuid_t nordicUUID;
rgrover1 109:425faebc8201 97 nordicUUID.uuid = uuid.getShortUUID();
rgrover1 109:425faebc8201 98 nordicUUID.type = BLE_UUID_TYPE_UNKNOWN; /* to be set below */
Rohit Grover 22:c6ee8136847e 99
Rohit Grover 22:c6ee8136847e 100 if (uuid.shortOrLong() == UUID::UUID_TYPE_SHORT) {
Rohit Grover 22:c6ee8136847e 101 nordicUUID.type = BLE_UUID_TYPE_BLE;
Rohit Grover 22:c6ee8136847e 102 } else {
Rohit Grover 22:c6ee8136847e 103 if (!lookupConvertedUUIDTable(uuid.getBaseUUID(), &nordicUUID.type)) {
Rohit Grover 22:c6ee8136847e 104 nordicUUID.type = custom_add_uuid_base(uuid.getBaseUUID());
Rohit Grover 22:c6ee8136847e 105 addToConvertedUUIDTable(uuid.getBaseUUID(), nordicUUID.type);
Rohit Grover 22:c6ee8136847e 106 }
Rohit Grover 22:c6ee8136847e 107 }
Rohit Grover 22:c6ee8136847e 108
Rohit Grover 22:c6ee8136847e 109 return nordicUUID;
Rohit Grover 22:c6ee8136847e 110 }
Rohit Grover 22:c6ee8136847e 111
Rohit Grover 22:c6ee8136847e 112 /**************************************************************************/
Rohit Grover 22:c6ee8136847e 113 /*!
Rohit Grover 22:c6ee8136847e 114 @brief Adds the base UUID to the custom service. All UUIDs used
Rohit Grover 22:c6ee8136847e 115 by this service are based on this 128-bit UUID.
Rohit Grover 22:c6ee8136847e 116
Rohit Grover 22:c6ee8136847e 117 @note This UUID needs to be added to the SoftDevice stack before
Rohit Grover 22:c6ee8136847e 118 adding the service's primary service via
Rohit Grover 22:c6ee8136847e 119 'sd_ble_gatts_service_add'
Rohit Grover 22:c6ee8136847e 120
Rohit Grover 22:c6ee8136847e 121 @param[in] p_uuid_base A pointer to the 128-bit UUID array (8*16)
Rohit Grover 22:c6ee8136847e 122
Rohit Grover 22:c6ee8136847e 123 @returns The UUID type.
Rohit Grover 22:c6ee8136847e 124 A return value of 0 should be considered an error.
Rohit Grover 22:c6ee8136847e 125
Rohit Grover 22:c6ee8136847e 126 @retval 0x00 BLE_UUID_TYPE_UNKNOWN
Rohit Grover 22:c6ee8136847e 127 @retval 0x01 BLE_UUID_TYPE_BLE
Rohit Grover 22:c6ee8136847e 128 @retval 0x02 BLE_UUID_TYPE_VENDOR_BEGIN
Rohit Grover 22:c6ee8136847e 129
Rohit Grover 22:c6ee8136847e 130 @section EXAMPLE
Rohit Grover 22:c6ee8136847e 131 @code
Rohit Grover 22:c6ee8136847e 132
Rohit Grover 22:c6ee8136847e 133 // Take note that bytes 2/3 are blank since these are used to identify
Rohit Grover 22:c6ee8136847e 134 // the primary service and individual characteristics
Rohit Grover 22:c6ee8136847e 135 #define CFG_CUSTOM_UUID_BASE "\x6E\x40\x00\x00\xB5\xA3\xF3\x93\xE0\xA9\xE5\x0E\x24\xDC\xCA\x9E"
Rohit Grover 22:c6ee8136847e 136
Rohit Grover 22:c6ee8136847e 137 uint8_t uuid_type = custom_add_uuid_base(CFG_CUSTOM_UUID_BASE);
Rohit Grover 22:c6ee8136847e 138 ASSERT(uuid_type > 0, ERROR_NOT_FOUND);
Rohit Grover 22:c6ee8136847e 139
Rohit Grover 22:c6ee8136847e 140 // We can now safely add the primary service and any characteristics
Rohit Grover 22:c6ee8136847e 141 // for our custom service ...
Rohit Grover 22:c6ee8136847e 142
Rohit Grover 22:c6ee8136847e 143 @endcode
Rohit Grover 22:c6ee8136847e 144 */
Rohit Grover 22:c6ee8136847e 145 /**************************************************************************/
Rohit Grover 22:c6ee8136847e 146 uint8_t custom_add_uuid_base(uint8_t const *const p_uuid_base)
Rohit Grover 22:c6ee8136847e 147 {
Rohit Grover 22:c6ee8136847e 148 ble_uuid128_t base_uuid;
Rohit Grover 22:c6ee8136847e 149 uint8_t uuid_type = 0;
Rohit Grover 22:c6ee8136847e 150
Rohit Grover 22:c6ee8136847e 151 /* Reverse the bytes since ble_uuid128_t is LSB */
rgrover1 97:e95e35845e1c 152 for (unsigned i = 0; i < LENGTH_OF_LONG_UUID; i++) {
rgrover1 97:e95e35845e1c 153 base_uuid.uuid128[i] = p_uuid_base[LENGTH_OF_LONG_UUID - 1 - i];
Rohit Grover 22:c6ee8136847e 154 }
Rohit Grover 22:c6ee8136847e 155
Rohit Grover 22:c6ee8136847e 156 ASSERT_INT( ERROR_NONE, sd_ble_uuid_vs_add( &base_uuid, &uuid_type ), 0);
Rohit Grover 22:c6ee8136847e 157
Rohit Grover 22:c6ee8136847e 158 return uuid_type;
Rohit Grover 22:c6ee8136847e 159 }
Rohit Grover 22:c6ee8136847e 160
Rohit Grover 22:c6ee8136847e 161 /**************************************************************************/
Rohit Grover 22:c6ee8136847e 162 /*!
Rohit Grover 22:c6ee8136847e 163
Rohit Grover 22:c6ee8136847e 164 */
Rohit Grover 22:c6ee8136847e 165 /**************************************************************************/
Rohit Grover 22:c6ee8136847e 166 error_t custom_decode_uuid_base(uint8_t const *const p_uuid_base,
Rohit Grover 22:c6ee8136847e 167 ble_uuid_t *p_uuid)
Rohit Grover 22:c6ee8136847e 168 {
Rohit Grover 56:a1071b629aa3 169 LongUUIDBytes_t uuid_base_le;
Rohit Grover 22:c6ee8136847e 170
Rohit Grover 22:c6ee8136847e 171 /* Reverse the bytes since ble_uuid128_t is LSB */
rgrover1 97:e95e35845e1c 172 for (uint8_t i = 0; i < LENGTH_OF_LONG_UUID; i++) {
rgrover1 97:e95e35845e1c 173 uuid_base_le[i] = p_uuid_base[LENGTH_OF_LONG_UUID - 1 - i];
Rohit Grover 22:c6ee8136847e 174 }
Rohit Grover 22:c6ee8136847e 175
rgrover1 97:e95e35845e1c 176 ASSERT_STATUS( sd_ble_uuid_decode(LENGTH_OF_LONG_UUID, uuid_base_le, p_uuid));
Rohit Grover 22:c6ee8136847e 177
Rohit Grover 22:c6ee8136847e 178 return ERROR_NONE;
Rohit Grover 22:c6ee8136847e 179 }
Rohit Grover 22:c6ee8136847e 180
Rohit Grover 22:c6ee8136847e 181 /**************************************************************************/
Rohit Grover 22:c6ee8136847e 182 /*!
Rohit Grover 22:c6ee8136847e 183 @brief Adds a new characteristic to the custom service, assigning
Rohit Grover 22:c6ee8136847e 184 properties, a UUID add-on value, etc.
Rohit Grover 22:c6ee8136847e 185
Rohit Grover 22:c6ee8136847e 186 @param[in] service_handle
Rohit Grover 22:c6ee8136847e 187 @param[in] p_uuid The 16-bit value to add to the base UUID
Rohit Grover 22:c6ee8136847e 188 for this characteristic (normally >1
Rohit Grover 22:c6ee8136847e 189 since 1 is typically used by the primary
Rohit Grover 22:c6ee8136847e 190 service).
Rohit Grover 22:c6ee8136847e 191 @param[in] char_props The characteristic properties, as
Rohit Grover 22:c6ee8136847e 192 defined by ble_gatt_char_props_t
Rohit Grover 22:c6ee8136847e 193 @param[in] max_length The maximum length of this characeristic
Rohit Grover 22:c6ee8136847e 194 @param[in] p_char_handle
Rohit Grover 22:c6ee8136847e 195
Rohit Grover 22:c6ee8136847e 196 @returns
Rohit Grover 22:c6ee8136847e 197 @retval ERROR_NONE Everything executed normally
Rohit Grover 22:c6ee8136847e 198 */
Rohit Grover 22:c6ee8136847e 199 /**************************************************************************/
Rohit Grover 22:c6ee8136847e 200 error_t custom_add_in_characteristic(uint16_t service_handle,
Rohit Grover 22:c6ee8136847e 201 ble_uuid_t *p_uuid,
Rohit Grover 22:c6ee8136847e 202 uint8_t properties,
Rohit Grover 22:c6ee8136847e 203 uint8_t *p_data,
Rohit Grover 22:c6ee8136847e 204 uint16_t min_length,
Rohit Grover 22:c6ee8136847e 205 uint16_t max_length,
rgrover1 83:71302acf1804 206 bool readAuthorization,
rgrover1 82:6c51cbe4bc12 207 bool writeAuthorization,
Rohit Grover 22:c6ee8136847e 208 ble_gatts_char_handles_t *p_char_handle)
Rohit Grover 22:c6ee8136847e 209 {
Rohit Grover 22:c6ee8136847e 210 /* Characteristic metadata */
Rohit Grover 22:c6ee8136847e 211 ble_gatts_attr_md_t cccd_md;
Rohit Grover 22:c6ee8136847e 212 ble_gatt_char_props_t char_props;
Rohit Grover 22:c6ee8136847e 213
Rohit Grover 22:c6ee8136847e 214 memcpy(&char_props, &properties, 1);
Rohit Grover 22:c6ee8136847e 215
Rohit Grover 22:c6ee8136847e 216 if (char_props.notify || char_props.indicate) {
Rohit Grover 22:c6ee8136847e 217 /* Notification requires cccd */
Rohit Grover 22:c6ee8136847e 218 memclr_( &cccd_md, sizeof(ble_gatts_attr_md_t));
Rohit Grover 22:c6ee8136847e 219 cccd_md.vloc = BLE_GATTS_VLOC_STACK;
Rohit Grover 22:c6ee8136847e 220 BLE_GAP_CONN_SEC_MODE_SET_OPEN(&cccd_md.read_perm);
Rohit Grover 22:c6ee8136847e 221 BLE_GAP_CONN_SEC_MODE_SET_OPEN(&cccd_md.write_perm);
Rohit Grover 22:c6ee8136847e 222 }
Rohit Grover 22:c6ee8136847e 223
Rohit Grover 22:c6ee8136847e 224 ble_gatts_char_md_t char_md = {0};
Rohit Grover 22:c6ee8136847e 225
Rohit Grover 22:c6ee8136847e 226 char_md.char_props = char_props;
Rohit Grover 22:c6ee8136847e 227 char_md.p_cccd_md =
Rohit Grover 22:c6ee8136847e 228 (char_props.notify || char_props.indicate) ? &cccd_md : NULL;
Rohit Grover 22:c6ee8136847e 229
Rohit Grover 22:c6ee8136847e 230 /* Attribute declaration */
rgrover1 84:658e5ec772a1 231 ble_gatts_attr_md_t attr_md = {0};
rgrover1 84:658e5ec772a1 232
rgrover1 84:658e5ec772a1 233 attr_md.rd_auth = readAuthorization;
rgrover1 84:658e5ec772a1 234 attr_md.wr_auth = writeAuthorization;
Rohit Grover 22:c6ee8136847e 235
Rohit Grover 22:c6ee8136847e 236 attr_md.vloc = BLE_GATTS_VLOC_STACK;
Rohit Grover 22:c6ee8136847e 237 attr_md.vlen = (min_length == max_length) ? 0 : 1;
Rohit Grover 22:c6ee8136847e 238
Rohit Grover 22:c6ee8136847e 239 if (char_props.read || char_props.notify || char_props.indicate) {
Rohit Grover 22:c6ee8136847e 240 BLE_GAP_CONN_SEC_MODE_SET_OPEN(&attr_md.read_perm);
Rohit Grover 22:c6ee8136847e 241 }
Rohit Grover 22:c6ee8136847e 242
marcuschang 85:17fe69405098 243 if (char_props.write || char_props.write_wo_resp) {
Rohit Grover 22:c6ee8136847e 244 BLE_GAP_CONN_SEC_MODE_SET_OPEN(&attr_md.write_perm);
Rohit Grover 22:c6ee8136847e 245 }
Rohit Grover 22:c6ee8136847e 246
Rohit Grover 22:c6ee8136847e 247 ble_gatts_attr_t attr_char_value = {0};
Rohit Grover 22:c6ee8136847e 248
Rohit Grover 22:c6ee8136847e 249 attr_char_value.p_uuid = p_uuid;
Rohit Grover 22:c6ee8136847e 250 attr_char_value.p_attr_md = &attr_md;
Rohit Grover 22:c6ee8136847e 251 attr_char_value.init_len = min_length;
Rohit Grover 22:c6ee8136847e 252 attr_char_value.max_len = max_length;
Rohit Grover 22:c6ee8136847e 253 attr_char_value.p_value = p_data;
Rohit Grover 22:c6ee8136847e 254
Rohit Grover 22:c6ee8136847e 255 ASSERT_STATUS ( sd_ble_gatts_characteristic_add(service_handle,
Rohit Grover 22:c6ee8136847e 256 &char_md,
Rohit Grover 22:c6ee8136847e 257 &attr_char_value,
Rohit Grover 22:c6ee8136847e 258 p_char_handle));
Rohit Grover 22:c6ee8136847e 259
Rohit Grover 22:c6ee8136847e 260 return ERROR_NONE;
Rohit Grover 22:c6ee8136847e 261 }
Rohit Grover 59:2819e564b613 262
Rohit Grover 59:2819e564b613 263
Rohit Grover 59:2819e564b613 264
Rohit Grover 59:2819e564b613 265 /**************************************************************************/
Rohit Grover 59:2819e564b613 266 /*!
Rohit Grover 59:2819e564b613 267 @brief Adds a new descriptor to the custom service, assigning
Rohit Grover 59:2819e564b613 268 value, a UUID add-on value, etc.
Rohit Grover 59:2819e564b613 269
Rohit Grover 59:2819e564b613 270 @param[in] char_handle
Rohit Grover 59:2819e564b613 271 @param[in] p_uuid The 16-bit value to add to the base UUID
Rohit Grover 59:2819e564b613 272 for this descriptor (normally >1
Rohit Grover 59:2819e564b613 273 since 1 is typically used by the primary
Rohit Grover 59:2819e564b613 274 service).
Rohit Grover 59:2819e564b613 275 @param[in] max_length The maximum length of this descriptor
Rohit Grover 59:2819e564b613 276
Rohit Grover 59:2819e564b613 277 @returns
Rohit Grover 59:2819e564b613 278 @retval ERROR_NONE Everything executed normally
Rohit Grover 59:2819e564b613 279 */
Rohit Grover 59:2819e564b613 280 /**************************************************************************/
Rohit Grover 59:2819e564b613 281 error_t custom_add_in_descriptor(uint16_t char_handle,
Rohit Grover 59:2819e564b613 282 ble_uuid_t *p_uuid,
Rohit Grover 59:2819e564b613 283 uint8_t *p_data,
Rohit Grover 59:2819e564b613 284 uint16_t min_length,
Rohit Grover 59:2819e564b613 285 uint16_t max_length,
Rohit Grover 59:2819e564b613 286 uint16_t *p_desc_handle)
Rohit Grover 59:2819e564b613 287 {
Rohit Grover 59:2819e564b613 288 /* Descriptor metadata */
Rohit Grover 59:2819e564b613 289 ble_gatts_attr_md_t desc_md = {0};
Rohit Grover 59:2819e564b613 290
Rohit Grover 59:2819e564b613 291 desc_md.vloc = BLE_GATTS_VLOC_STACK;
Rohit Grover 59:2819e564b613 292 desc_md.vlen = (min_length == max_length) ? 0 : 1;
Rohit Grover 59:2819e564b613 293
Rohit Grover 59:2819e564b613 294 /* Make it readable and writable */
Rohit Grover 59:2819e564b613 295 BLE_GAP_CONN_SEC_MODE_SET_OPEN(&desc_md.read_perm);
Rohit Grover 59:2819e564b613 296 BLE_GAP_CONN_SEC_MODE_SET_OPEN(&desc_md.write_perm);
Rohit Grover 59:2819e564b613 297
Rohit Grover 59:2819e564b613 298 ble_gatts_attr_t attr_desc = {0};
Rohit Grover 59:2819e564b613 299
Rohit Grover 59:2819e564b613 300 attr_desc.p_uuid = p_uuid;
Rohit Grover 59:2819e564b613 301 attr_desc.p_attr_md = &desc_md;
Rohit Grover 59:2819e564b613 302 attr_desc.init_len = min_length;
Rohit Grover 59:2819e564b613 303 attr_desc.max_len = max_length;
Rohit Grover 59:2819e564b613 304 attr_desc.p_value = p_data;
Rohit Grover 59:2819e564b613 305
Rohit Grover 59:2819e564b613 306 ASSERT_STATUS ( sd_ble_gatts_descriptor_add(char_handle,
Rohit Grover 59:2819e564b613 307 &attr_desc,
Rohit Grover 59:2819e564b613 308 p_desc_handle));
Rohit Grover 59:2819e564b613 309
Rohit Grover 59:2819e564b613 310 return ERROR_NONE;
rgrover1 82:6c51cbe4bc12 311 }