smart ball test board code

Dependencies:   nrf51-sdk

Fork of nRF51822 by Nordic Semiconductor

Committer:
vcoubard
Date:
Mon Jan 11 10:19:18 2016 +0000
Revision:
566:cf03471a4ec4
Parent:
564:9c4b96f7be8d
Child:
567:e425ad9e5d6e
Synchronized with git rev 0bcc2e96
Author: Andres Amaya Garcia
Modify shutdown due to BLE API change

The module is updated to comply with the changes to BLE API regarding correct
shutdown functionality. The following changes are introduced to ble-nrf51822:

* Calls to the old static function shutdown in Gap, GattClient, GattServer and
SecurityManager are removed.
* The cleanup function in Gap, GattClient, GattServer and SecurityManager is
renamed to `reset()` and made public.
* The static references inside nRF5xGap, nRF5xGattClient, nRF5xGattServer and
nRF5xSecurityManager to objects of their own class are moved to nRF5xn.
* The static getInstance accessors in nRF5xGap, nRF5xGattClient,
nRF5xGattServer and nRF5xSecurityManager are removed and their functionality is
moved to the implemented virtual accessors in nRF5xn i.e. getGap(),
getGattClient, etc.
* A static function Instance is added to nRF5xn class to make the transport
object accessible across the module.

Who changed what in which revision?

UserRevisionLine numberNew contents of line
vcoubard 542:884f95bf5351 1 /* mbed Microcontroller Library
vcoubard 542:884f95bf5351 2 * Copyright (c) 2006-2013 ARM Limited
vcoubard 542:884f95bf5351 3 *
vcoubard 542:884f95bf5351 4 * Licensed under the Apache License, Version 2.0 (the "License");
vcoubard 542:884f95bf5351 5 * you may not use this file except in compliance with the License.
vcoubard 542:884f95bf5351 6 * You may obtain a copy of the License at
vcoubard 542:884f95bf5351 7 *
vcoubard 542:884f95bf5351 8 * http://www.apache.org/licenses/LICENSE-2.0
vcoubard 542:884f95bf5351 9 *
vcoubard 542:884f95bf5351 10 * Unless required by applicable law or agreed to in writing, software
vcoubard 542:884f95bf5351 11 * distributed under the License is distributed on an "AS IS" BASIS,
vcoubard 542:884f95bf5351 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
vcoubard 542:884f95bf5351 13 * See the License for the specific language governing permissions and
vcoubard 542:884f95bf5351 14 * limitations under the License.
vcoubard 542:884f95bf5351 15 */
vcoubard 542:884f95bf5351 16
vcoubard 542:884f95bf5351 17 #include "nRF5xGattServer.h"
vcoubard 542:884f95bf5351 18 #include "mbed.h"
vcoubard 542:884f95bf5351 19
vcoubard 542:884f95bf5351 20 #include "common/common.h"
vcoubard 542:884f95bf5351 21 #include "btle/custom/custom_helper.h"
vcoubard 542:884f95bf5351 22
vcoubard 566:cf03471a4ec4 23 #include "nRF5xn.h"
vcoubard 542:884f95bf5351 24
vcoubard 542:884f95bf5351 25 /**************************************************************************/
vcoubard 542:884f95bf5351 26 /*!
vcoubard 542:884f95bf5351 27 @brief Adds a new service to the GATT table on the peripheral
vcoubard 542:884f95bf5351 28
vcoubard 542:884f95bf5351 29 @returns ble_error_t
vcoubard 542:884f95bf5351 30
vcoubard 542:884f95bf5351 31 @retval BLE_ERROR_NONE
vcoubard 542:884f95bf5351 32 Everything executed properly
vcoubard 542:884f95bf5351 33
vcoubard 542:884f95bf5351 34 @section EXAMPLE
vcoubard 542:884f95bf5351 35
vcoubard 542:884f95bf5351 36 @code
vcoubard 542:884f95bf5351 37
vcoubard 542:884f95bf5351 38 @endcode
vcoubard 542:884f95bf5351 39 */
vcoubard 542:884f95bf5351 40 /**************************************************************************/
vcoubard 542:884f95bf5351 41 ble_error_t nRF5xGattServer::addService(GattService &service)
vcoubard 542:884f95bf5351 42 {
vcoubard 542:884f95bf5351 43 /* ToDo: Make sure this service UUID doesn't already exist (?) */
vcoubard 542:884f95bf5351 44 /* ToDo: Basic validation */
vcoubard 542:884f95bf5351 45
vcoubard 542:884f95bf5351 46 /* Add the service to the nRF51 */
vcoubard 542:884f95bf5351 47 ble_uuid_t nordicUUID;
vcoubard 542:884f95bf5351 48 nordicUUID = custom_convert_to_nordic_uuid(service.getUUID());
vcoubard 542:884f95bf5351 49
vcoubard 542:884f95bf5351 50 uint16_t serviceHandle;
vcoubard 542:884f95bf5351 51 ASSERT( ERROR_NONE ==
vcoubard 542:884f95bf5351 52 sd_ble_gatts_service_add(BLE_GATTS_SRVC_TYPE_PRIMARY,
vcoubard 542:884f95bf5351 53 &nordicUUID,
vcoubard 542:884f95bf5351 54 &serviceHandle),
vcoubard 542:884f95bf5351 55 BLE_ERROR_PARAM_OUT_OF_RANGE );
vcoubard 542:884f95bf5351 56 service.setHandle(serviceHandle);
vcoubard 542:884f95bf5351 57
vcoubard 542:884f95bf5351 58 /* Add characteristics to the service */
vcoubard 542:884f95bf5351 59 for (uint8_t i = 0; i < service.getCharacteristicCount(); i++) {
vcoubard 542:884f95bf5351 60 if (characteristicCount >= BLE_TOTAL_CHARACTERISTICS) {
vcoubard 542:884f95bf5351 61 return BLE_ERROR_NO_MEM;
vcoubard 542:884f95bf5351 62 }
vcoubard 542:884f95bf5351 63 GattCharacteristic *p_char = service.getCharacteristic(i);
vcoubard 542:884f95bf5351 64
vcoubard 542:884f95bf5351 65 /* Skip any incompletely defined, read-only characteristics. */
vcoubard 542:884f95bf5351 66 if ((p_char->getValueAttribute().getValuePtr() == NULL) &&
vcoubard 553:20b282c26f96 67 (p_char->getValueAttribute().getLength() == 0) &&
vcoubard 542:884f95bf5351 68 (p_char->getProperties() == GattCharacteristic::BLE_GATT_CHAR_PROPERTIES_READ)) {
vcoubard 542:884f95bf5351 69 continue;
vcoubard 542:884f95bf5351 70 }
vcoubard 542:884f95bf5351 71
vcoubard 542:884f95bf5351 72 nordicUUID = custom_convert_to_nordic_uuid(p_char->getValueAttribute().getUUID());
vcoubard 542:884f95bf5351 73
vcoubard 542:884f95bf5351 74 /* The user-description descriptor is a special case which needs to be
vcoubard 542:884f95bf5351 75 * handled at the time of adding the characteristic. The following block
vcoubard 542:884f95bf5351 76 * is meant to discover its presence. */
vcoubard 542:884f95bf5351 77 const uint8_t *userDescriptionDescriptorValuePtr = NULL;
vcoubard 542:884f95bf5351 78 uint16_t userDescriptionDescriptorValueLen = 0;
vcoubard 542:884f95bf5351 79 for (uint8_t j = 0; j < p_char->getDescriptorCount(); j++) {
vcoubard 542:884f95bf5351 80 GattAttribute *p_desc = p_char->getDescriptor(j);
vcoubard 542:884f95bf5351 81 if (p_desc->getUUID() == BLE_UUID_DESCRIPTOR_CHAR_USER_DESC) {
vcoubard 542:884f95bf5351 82 userDescriptionDescriptorValuePtr = p_desc->getValuePtr();
vcoubard 542:884f95bf5351 83 userDescriptionDescriptorValueLen = p_desc->getLength();
vcoubard 542:884f95bf5351 84 }
vcoubard 542:884f95bf5351 85 }
vcoubard 542:884f95bf5351 86
vcoubard 542:884f95bf5351 87 ASSERT ( ERROR_NONE ==
vcoubard 542:884f95bf5351 88 custom_add_in_characteristic(BLE_GATT_HANDLE_INVALID,
vcoubard 542:884f95bf5351 89 &nordicUUID,
vcoubard 542:884f95bf5351 90 p_char->getProperties(),
vcoubard 542:884f95bf5351 91 p_char->getRequiredSecurity(),
vcoubard 542:884f95bf5351 92 p_char->getValueAttribute().getValuePtr(),
vcoubard 553:20b282c26f96 93 p_char->getValueAttribute().getLength(),
vcoubard 542:884f95bf5351 94 p_char->getValueAttribute().getMaxLength(),
vcoubard 554:2a413611e569 95 p_char->getValueAttribute().hasVariableLength(),
vcoubard 542:884f95bf5351 96 userDescriptionDescriptorValuePtr,
vcoubard 542:884f95bf5351 97 userDescriptionDescriptorValueLen,
vcoubard 542:884f95bf5351 98 p_char->isReadAuthorizationEnabled(),
vcoubard 542:884f95bf5351 99 p_char->isWriteAuthorizationEnabled(),
vcoubard 542:884f95bf5351 100 &nrfCharacteristicHandles[characteristicCount]),
vcoubard 542:884f95bf5351 101 BLE_ERROR_PARAM_OUT_OF_RANGE );
vcoubard 542:884f95bf5351 102
vcoubard 542:884f95bf5351 103 /* Update the characteristic handle */
vcoubard 542:884f95bf5351 104 p_characteristics[characteristicCount] = p_char;
vcoubard 542:884f95bf5351 105 p_char->getValueAttribute().setHandle(nrfCharacteristicHandles[characteristicCount].value_handle);
vcoubard 542:884f95bf5351 106 characteristicCount++;
vcoubard 542:884f95bf5351 107
vcoubard 542:884f95bf5351 108 /* Add optional descriptors if any */
vcoubard 542:884f95bf5351 109 for (uint8_t j = 0; j < p_char->getDescriptorCount(); j++) {
vcoubard 542:884f95bf5351 110 if (descriptorCount >= BLE_TOTAL_DESCRIPTORS) {
vcoubard 542:884f95bf5351 111 return BLE_ERROR_NO_MEM;
vcoubard 542:884f95bf5351 112 }
vcoubard 542:884f95bf5351 113
vcoubard 542:884f95bf5351 114 GattAttribute *p_desc = p_char->getDescriptor(j);
vcoubard 542:884f95bf5351 115 /* skip the user-description-descriptor here; this has already been handled when adding the characteristic (above). */
vcoubard 542:884f95bf5351 116 if (p_desc->getUUID() == BLE_UUID_DESCRIPTOR_CHAR_USER_DESC) {
vcoubard 542:884f95bf5351 117 continue;
vcoubard 542:884f95bf5351 118 }
vcoubard 542:884f95bf5351 119
vcoubard 542:884f95bf5351 120 nordicUUID = custom_convert_to_nordic_uuid(p_desc->getUUID());
vcoubard 542:884f95bf5351 121
vcoubard 542:884f95bf5351 122 ASSERT(ERROR_NONE ==
vcoubard 542:884f95bf5351 123 custom_add_in_descriptor(BLE_GATT_HANDLE_INVALID,
vcoubard 542:884f95bf5351 124 &nordicUUID,
vcoubard 542:884f95bf5351 125 p_desc->getValuePtr(),
vcoubard 553:20b282c26f96 126 p_desc->getLength(),
vcoubard 542:884f95bf5351 127 p_desc->getMaxLength(),
vcoubard 554:2a413611e569 128 p_desc->hasVariableLength(),
vcoubard 542:884f95bf5351 129 &nrfDescriptorHandles[descriptorCount]),
vcoubard 542:884f95bf5351 130 BLE_ERROR_PARAM_OUT_OF_RANGE);
vcoubard 542:884f95bf5351 131
vcoubard 542:884f95bf5351 132 p_descriptors[descriptorCount++] = p_desc;
vcoubard 542:884f95bf5351 133 p_desc->setHandle(nrfDescriptorHandles[descriptorCount]);
vcoubard 542:884f95bf5351 134 }
vcoubard 542:884f95bf5351 135 }
vcoubard 542:884f95bf5351 136
vcoubard 542:884f95bf5351 137 serviceCount++;
vcoubard 542:884f95bf5351 138
vcoubard 542:884f95bf5351 139 return BLE_ERROR_NONE;
vcoubard 542:884f95bf5351 140 }
vcoubard 542:884f95bf5351 141
vcoubard 542:884f95bf5351 142 /**************************************************************************/
vcoubard 542:884f95bf5351 143 /*!
vcoubard 542:884f95bf5351 144 @brief Reads the value of a characteristic, based on the service
vcoubard 542:884f95bf5351 145 and characteristic index fields
vcoubard 542:884f95bf5351 146
vcoubard 542:884f95bf5351 147 @param[in] attributeHandle
vcoubard 542:884f95bf5351 148 The handle of the GattCharacteristic to read from
vcoubard 542:884f95bf5351 149 @param[in] buffer
vcoubard 542:884f95bf5351 150 Buffer to hold the the characteristic's value
vcoubard 542:884f95bf5351 151 (raw byte array in LSB format)
vcoubard 542:884f95bf5351 152 @param[in/out] len
vcoubard 542:884f95bf5351 153 input: Length in bytes to be read.
vcoubard 542:884f95bf5351 154 output: Total length of attribute value upon successful return.
vcoubard 542:884f95bf5351 155
vcoubard 542:884f95bf5351 156 @returns ble_error_t
vcoubard 542:884f95bf5351 157
vcoubard 542:884f95bf5351 158 @retval BLE_ERROR_NONE
vcoubard 542:884f95bf5351 159 Everything executed properly
vcoubard 542:884f95bf5351 160 */
vcoubard 542:884f95bf5351 161 /**************************************************************************/
vcoubard 542:884f95bf5351 162 ble_error_t nRF5xGattServer::read(GattAttribute::Handle_t attributeHandle, uint8_t buffer[], uint16_t *lengthP)
vcoubard 542:884f95bf5351 163 {
vcoubard 542:884f95bf5351 164 return read(BLE_CONN_HANDLE_INVALID, attributeHandle, buffer, lengthP);
vcoubard 542:884f95bf5351 165 }
vcoubard 542:884f95bf5351 166
vcoubard 542:884f95bf5351 167 ble_error_t nRF5xGattServer::read(Gap::Handle_t connectionHandle, GattAttribute::Handle_t attributeHandle, uint8_t buffer[], uint16_t *lengthP)
vcoubard 542:884f95bf5351 168 {
vcoubard 542:884f95bf5351 169 ble_gatts_value_t value = {
vcoubard 542:884f95bf5351 170 .len = *lengthP,
vcoubard 542:884f95bf5351 171 .offset = 0,
vcoubard 542:884f95bf5351 172 .p_value = buffer,
vcoubard 542:884f95bf5351 173 };
vcoubard 542:884f95bf5351 174
vcoubard 542:884f95bf5351 175 ASSERT( ERROR_NONE ==
vcoubard 542:884f95bf5351 176 sd_ble_gatts_value_get(connectionHandle, attributeHandle, &value),
vcoubard 542:884f95bf5351 177 BLE_ERROR_PARAM_OUT_OF_RANGE);
vcoubard 542:884f95bf5351 178 *lengthP = value.len;
vcoubard 542:884f95bf5351 179
vcoubard 542:884f95bf5351 180 return BLE_ERROR_NONE;
vcoubard 542:884f95bf5351 181 }
vcoubard 542:884f95bf5351 182
vcoubard 542:884f95bf5351 183 /**************************************************************************/
vcoubard 542:884f95bf5351 184 /*!
vcoubard 542:884f95bf5351 185 @brief Updates the value of a characteristic, based on the service
vcoubard 542:884f95bf5351 186 and characteristic index fields
vcoubard 542:884f95bf5351 187
vcoubard 542:884f95bf5351 188 @param[in] charHandle
vcoubard 542:884f95bf5351 189 The handle of the GattCharacteristic to write to
vcoubard 542:884f95bf5351 190 @param[in] buffer
vcoubard 542:884f95bf5351 191 Data to use when updating the characteristic's value
vcoubard 542:884f95bf5351 192 (raw byte array in LSB format)
vcoubard 542:884f95bf5351 193 @param[in] len
vcoubard 542:884f95bf5351 194 The number of bytes in buffer
vcoubard 542:884f95bf5351 195
vcoubard 542:884f95bf5351 196 @returns ble_error_t
vcoubard 542:884f95bf5351 197
vcoubard 542:884f95bf5351 198 @retval BLE_ERROR_NONE
vcoubard 542:884f95bf5351 199 Everything executed properly
vcoubard 542:884f95bf5351 200 */
vcoubard 542:884f95bf5351 201 /**************************************************************************/
vcoubard 542:884f95bf5351 202 ble_error_t nRF5xGattServer::write(GattAttribute::Handle_t attributeHandle, const uint8_t buffer[], uint16_t len, bool localOnly)
vcoubard 542:884f95bf5351 203 {
vcoubard 542:884f95bf5351 204 return write(BLE_CONN_HANDLE_INVALID, attributeHandle, buffer, len, localOnly);
vcoubard 542:884f95bf5351 205 }
vcoubard 542:884f95bf5351 206
vcoubard 542:884f95bf5351 207 ble_error_t nRF5xGattServer::write(Gap::Handle_t connectionHandle, GattAttribute::Handle_t attributeHandle, const uint8_t buffer[], uint16_t len, bool localOnly)
vcoubard 542:884f95bf5351 208 {
vcoubard 542:884f95bf5351 209 ble_error_t returnValue = BLE_ERROR_NONE;
vcoubard 542:884f95bf5351 210
vcoubard 542:884f95bf5351 211 ble_gatts_value_t value = {
vcoubard 542:884f95bf5351 212 .len = len,
vcoubard 542:884f95bf5351 213 .offset = 0,
vcoubard 542:884f95bf5351 214 .p_value = const_cast<uint8_t *>(buffer),
vcoubard 542:884f95bf5351 215 };
vcoubard 542:884f95bf5351 216
vcoubard 542:884f95bf5351 217 if (localOnly) {
vcoubard 542:884f95bf5351 218 /* Only update locally regardless of notify/indicate */
vcoubard 542:884f95bf5351 219 ASSERT_INT( ERROR_NONE,
vcoubard 542:884f95bf5351 220 sd_ble_gatts_value_set(connectionHandle, attributeHandle, &value),
vcoubard 542:884f95bf5351 221 BLE_ERROR_PARAM_OUT_OF_RANGE );
vcoubard 542:884f95bf5351 222 return BLE_ERROR_NONE;
vcoubard 542:884f95bf5351 223 }
vcoubard 542:884f95bf5351 224
vcoubard 542:884f95bf5351 225 int characteristicIndex = resolveValueHandleToCharIndex(attributeHandle);
vcoubard 542:884f95bf5351 226 if ((characteristicIndex != -1) &&
vcoubard 542:884f95bf5351 227 (p_characteristics[characteristicIndex]->getProperties() & (GattCharacteristic::BLE_GATT_CHAR_PROPERTIES_INDICATE | GattCharacteristic::BLE_GATT_CHAR_PROPERTIES_NOTIFY))) {
vcoubard 542:884f95bf5351 228 /* HVX update for the characteristic value */
vcoubard 542:884f95bf5351 229 ble_gatts_hvx_params_t hvx_params;
vcoubard 542:884f95bf5351 230
vcoubard 542:884f95bf5351 231 hvx_params.handle = attributeHandle;
vcoubard 542:884f95bf5351 232 hvx_params.type =
vcoubard 542:884f95bf5351 233 (p_characteristics[characteristicIndex]->getProperties() & GattCharacteristic::BLE_GATT_CHAR_PROPERTIES_NOTIFY) ? BLE_GATT_HVX_NOTIFICATION : BLE_GATT_HVX_INDICATION;
vcoubard 542:884f95bf5351 234 hvx_params.offset = 0;
vcoubard 542:884f95bf5351 235 hvx_params.p_data = const_cast<uint8_t *>(buffer);
vcoubard 542:884f95bf5351 236 hvx_params.p_len = &len;
vcoubard 542:884f95bf5351 237
vcoubard 542:884f95bf5351 238 if (connectionHandle == BLE_CONN_HANDLE_INVALID) { /* use the default connection handle if the caller hasn't specified a valid connectionHandle. */
vcoubard 566:cf03471a4ec4 239 nRF5xGap &gap = (nRF5xGap &) nRF5xn::Instance(BLE::DEFAULT_INSTANCE).getGap();
vcoubard 566:cf03471a4ec4 240 connectionHandle = gap.getConnectionHandle();
vcoubard 542:884f95bf5351 241 }
vcoubard 542:884f95bf5351 242 error_t error = (error_t) sd_ble_gatts_hvx(connectionHandle, &hvx_params);
vcoubard 542:884f95bf5351 243 if (error != ERROR_NONE) {
vcoubard 542:884f95bf5351 244 switch (error) {
vcoubard 542:884f95bf5351 245 case ERROR_BLE_NO_TX_BUFFERS: /* Notifications consume application buffers. The return value can be used for resending notifications. */
vcoubard 542:884f95bf5351 246 case ERROR_BUSY:
vcoubard 542:884f95bf5351 247 returnValue = BLE_STACK_BUSY;
vcoubard 542:884f95bf5351 248 break;
vcoubard 542:884f95bf5351 249
vcoubard 542:884f95bf5351 250 case ERROR_INVALID_STATE:
vcoubard 542:884f95bf5351 251 case ERROR_BLEGATTS_SYS_ATTR_MISSING:
vcoubard 542:884f95bf5351 252 returnValue = BLE_ERROR_INVALID_STATE;
vcoubard 542:884f95bf5351 253 break;
vcoubard 542:884f95bf5351 254
vcoubard 542:884f95bf5351 255 default :
vcoubard 542:884f95bf5351 256 ASSERT_INT( ERROR_NONE,
vcoubard 542:884f95bf5351 257 sd_ble_gatts_value_set(connectionHandle, attributeHandle, &value),
vcoubard 542:884f95bf5351 258 BLE_ERROR_PARAM_OUT_OF_RANGE );
vcoubard 542:884f95bf5351 259
vcoubard 542:884f95bf5351 260 /* Notifications consume application buffers. The return value can
vcoubard 542:884f95bf5351 261 * be used for resending notifications. */
vcoubard 542:884f95bf5351 262 returnValue = BLE_STACK_BUSY;
vcoubard 542:884f95bf5351 263 break;
vcoubard 542:884f95bf5351 264 }
vcoubard 542:884f95bf5351 265 }
vcoubard 542:884f95bf5351 266 } else {
vcoubard 542:884f95bf5351 267 returnValue = BLE_ERROR_INVALID_STATE; // if assert is not used
vcoubard 542:884f95bf5351 268 ASSERT_INT( ERROR_NONE,
vcoubard 542:884f95bf5351 269 sd_ble_gatts_value_set(connectionHandle, attributeHandle, &value),
vcoubard 542:884f95bf5351 270 BLE_ERROR_PARAM_OUT_OF_RANGE );
vcoubard 542:884f95bf5351 271 }
vcoubard 542:884f95bf5351 272
vcoubard 542:884f95bf5351 273 return returnValue;
vcoubard 542:884f95bf5351 274 }
vcoubard 542:884f95bf5351 275
vcoubard 542:884f95bf5351 276 ble_error_t nRF5xGattServer::areUpdatesEnabled(const GattCharacteristic &characteristic, bool *enabledP)
vcoubard 542:884f95bf5351 277 {
vcoubard 542:884f95bf5351 278 /* Forward the call with the default connection handle. */
vcoubard 566:cf03471a4ec4 279 nRF5xGap &gap = (nRF5xGap &) nRF5xn::Instance(BLE::DEFAULT_INSTANCE).getGap();
vcoubard 566:cf03471a4ec4 280 return areUpdatesEnabled(gap.getConnectionHandle(), characteristic, enabledP);
vcoubard 542:884f95bf5351 281 }
vcoubard 542:884f95bf5351 282
vcoubard 542:884f95bf5351 283 ble_error_t nRF5xGattServer::areUpdatesEnabled(Gap::Handle_t connectionHandle, const GattCharacteristic &characteristic, bool *enabledP)
vcoubard 542:884f95bf5351 284 {
vcoubard 542:884f95bf5351 285 int characteristicIndex = resolveValueHandleToCharIndex(characteristic.getValueHandle());
vcoubard 542:884f95bf5351 286 if (characteristicIndex == -1) {
vcoubard 542:884f95bf5351 287 return BLE_ERROR_INVALID_PARAM;
vcoubard 542:884f95bf5351 288 }
vcoubard 542:884f95bf5351 289
vcoubard 542:884f95bf5351 290 /* Read the cccd value from the GATT server. */
vcoubard 542:884f95bf5351 291 GattAttribute::Handle_t cccdHandle = nrfCharacteristicHandles[characteristicIndex].cccd_handle;
vcoubard 542:884f95bf5351 292 uint16_t cccdValue;
vcoubard 542:884f95bf5351 293 uint16_t length = sizeof(cccdValue);
vcoubard 542:884f95bf5351 294 ble_error_t rc = read(connectionHandle, cccdHandle, reinterpret_cast<uint8_t *>(&cccdValue), &length);
vcoubard 542:884f95bf5351 295 if (rc != BLE_ERROR_NONE) {
vcoubard 542:884f95bf5351 296 return rc;
vcoubard 542:884f95bf5351 297 }
vcoubard 542:884f95bf5351 298 if (length != sizeof(cccdValue)) {
vcoubard 542:884f95bf5351 299 return BLE_ERROR_INVALID_STATE;
vcoubard 542:884f95bf5351 300 }
vcoubard 542:884f95bf5351 301
vcoubard 542:884f95bf5351 302 /* Check for NOTFICATION or INDICATION in CCCD. */
vcoubard 542:884f95bf5351 303 if ((cccdValue & BLE_GATT_HVX_NOTIFICATION) || (cccdValue & BLE_GATT_HVX_INDICATION)) {
vcoubard 542:884f95bf5351 304 *enabledP = true;
vcoubard 542:884f95bf5351 305 }
vcoubard 542:884f95bf5351 306
vcoubard 542:884f95bf5351 307 return BLE_ERROR_NONE;
vcoubard 542:884f95bf5351 308 }
vcoubard 542:884f95bf5351 309
vcoubard 542:884f95bf5351 310 /**************************************************************************/
vcoubard 542:884f95bf5351 311 /*!
vcoubard 566:cf03471a4ec4 312 @brief Clear nRF5xGattServer's state.
vcoubard 566:cf03471a4ec4 313
vcoubard 566:cf03471a4ec4 314 @returns ble_error_t
vcoubard 566:cf03471a4ec4 315
vcoubard 566:cf03471a4ec4 316 @retval BLE_ERROR_NONE
vcoubard 566:cf03471a4ec4 317 Everything executed properly
vcoubard 566:cf03471a4ec4 318 */
vcoubard 566:cf03471a4ec4 319 /**************************************************************************/
vcoubard 566:cf03471a4ec4 320 ble_error_t nRF5xGattServer::reset(void)
vcoubard 566:cf03471a4ec4 321 {
vcoubard 566:cf03471a4ec4 322 /* Clear all state that is from the parent, including private members */
vcoubard 566:cf03471a4ec4 323 if (GattServer::reset() != BLE_ERROR_NONE) {
vcoubard 566:cf03471a4ec4 324 return BLE_ERROR_INVALID_STATE;
vcoubard 566:cf03471a4ec4 325 }
vcoubard 566:cf03471a4ec4 326
vcoubard 566:cf03471a4ec4 327 /* Clear derived class members */
vcoubard 566:cf03471a4ec4 328 memset(p_characteristics, 0, sizeof(p_characteristics));
vcoubard 566:cf03471a4ec4 329 memset(p_descriptors, 0, sizeof(p_descriptors));
vcoubard 566:cf03471a4ec4 330 memset(nrfCharacteristicHandles, 0, sizeof(ble_gatts_char_handles_t));
vcoubard 566:cf03471a4ec4 331 memset(nrfDescriptorHandles, 0, sizeof(nrfDescriptorHandles));
vcoubard 566:cf03471a4ec4 332 descriptorCount = 0;
vcoubard 566:cf03471a4ec4 333
vcoubard 566:cf03471a4ec4 334 return BLE_ERROR_NONE;
vcoubard 566:cf03471a4ec4 335 }
vcoubard 566:cf03471a4ec4 336
vcoubard 566:cf03471a4ec4 337 /**************************************************************************/
vcoubard 566:cf03471a4ec4 338 /*!
vcoubard 542:884f95bf5351 339 @brief Callback handler for events getting pushed up from the SD
vcoubard 542:884f95bf5351 340 */
vcoubard 542:884f95bf5351 341 /**************************************************************************/
vcoubard 542:884f95bf5351 342 void nRF5xGattServer::hwCallback(ble_evt_t *p_ble_evt)
vcoubard 542:884f95bf5351 343 {
vcoubard 542:884f95bf5351 344 GattAttribute::Handle_t handle_value;
vcoubard 542:884f95bf5351 345 GattServerEvents::gattEvent_t eventType;
vcoubard 542:884f95bf5351 346 const ble_gatts_evt_t *gattsEventP = &p_ble_evt->evt.gatts_evt;
vcoubard 542:884f95bf5351 347
vcoubard 542:884f95bf5351 348 switch (p_ble_evt->header.evt_id) {
vcoubard 542:884f95bf5351 349 case BLE_GATTS_EVT_WRITE: {
vcoubard 542:884f95bf5351 350 /* There are 2 use case here: Values being updated & CCCD (indicate/notify) enabled */
vcoubard 542:884f95bf5351 351
vcoubard 542:884f95bf5351 352 /* 1.) Handle CCCD changes */
vcoubard 542:884f95bf5351 353 handle_value = gattsEventP->params.write.handle;
vcoubard 542:884f95bf5351 354 int characteristicIndex = resolveCCCDHandleToCharIndex(handle_value);
vcoubard 542:884f95bf5351 355 if ((characteristicIndex != -1) &&
vcoubard 542:884f95bf5351 356 (p_characteristics[characteristicIndex]->getProperties() &
vcoubard 542:884f95bf5351 357 (GattCharacteristic::BLE_GATT_CHAR_PROPERTIES_INDICATE | GattCharacteristic::BLE_GATT_CHAR_PROPERTIES_NOTIFY))) {
vcoubard 542:884f95bf5351 358
vcoubard 542:884f95bf5351 359 uint16_t cccd_value = (gattsEventP->params.write.data[1] << 8) | gattsEventP->params.write.data[0]; /* Little Endian but M0 may be mis-aligned */
vcoubard 542:884f95bf5351 360
vcoubard 542:884f95bf5351 361 if (((p_characteristics[characteristicIndex]->getProperties() & GattCharacteristic::BLE_GATT_CHAR_PROPERTIES_INDICATE) && (cccd_value & BLE_GATT_HVX_INDICATION)) ||
vcoubard 542:884f95bf5351 362 ((p_characteristics[characteristicIndex]->getProperties() & GattCharacteristic::BLE_GATT_CHAR_PROPERTIES_NOTIFY) && (cccd_value & BLE_GATT_HVX_NOTIFICATION))) {
vcoubard 542:884f95bf5351 363 eventType = GattServerEvents::GATT_EVENT_UPDATES_ENABLED;
vcoubard 542:884f95bf5351 364 } else {
vcoubard 542:884f95bf5351 365 eventType = GattServerEvents::GATT_EVENT_UPDATES_DISABLED;
vcoubard 542:884f95bf5351 366 }
vcoubard 542:884f95bf5351 367
vcoubard 542:884f95bf5351 368 handleEvent(eventType, p_characteristics[characteristicIndex]->getValueHandle());
vcoubard 542:884f95bf5351 369 return;
vcoubard 542:884f95bf5351 370 }
vcoubard 542:884f95bf5351 371
vcoubard 542:884f95bf5351 372 /* 2.) Changes to the characteristic value will be handled with other events below */
vcoubard 542:884f95bf5351 373 eventType = GattServerEvents::GATT_EVENT_DATA_WRITTEN;
vcoubard 542:884f95bf5351 374 }
vcoubard 542:884f95bf5351 375 break;
vcoubard 542:884f95bf5351 376
vcoubard 542:884f95bf5351 377 case BLE_GATTS_EVT_HVC:
vcoubard 542:884f95bf5351 378 /* Indication confirmation received */
vcoubard 542:884f95bf5351 379 eventType = GattServerEvents::GATT_EVENT_CONFIRMATION_RECEIVED;
vcoubard 542:884f95bf5351 380 handle_value = gattsEventP->params.hvc.handle;
vcoubard 542:884f95bf5351 381 break;
vcoubard 542:884f95bf5351 382
vcoubard 542:884f95bf5351 383 case BLE_EVT_TX_COMPLETE: {
vcoubard 542:884f95bf5351 384 handleDataSentEvent(p_ble_evt->evt.common_evt.params.tx_complete.count);
vcoubard 542:884f95bf5351 385 return;
vcoubard 542:884f95bf5351 386 }
vcoubard 542:884f95bf5351 387
vcoubard 542:884f95bf5351 388 case BLE_GATTS_EVT_SYS_ATTR_MISSING:
vcoubard 542:884f95bf5351 389 sd_ble_gatts_sys_attr_set(gattsEventP->conn_handle, NULL, 0, 0);
vcoubard 542:884f95bf5351 390 return;
vcoubard 542:884f95bf5351 391
vcoubard 542:884f95bf5351 392 case BLE_GATTS_EVT_RW_AUTHORIZE_REQUEST:
vcoubard 542:884f95bf5351 393 switch (gattsEventP->params.authorize_request.type) {
vcoubard 542:884f95bf5351 394 case BLE_GATTS_AUTHORIZE_TYPE_READ:
vcoubard 542:884f95bf5351 395 eventType = GattServerEvents::GATT_EVENT_READ_AUTHORIZATION_REQ;
vcoubard 542:884f95bf5351 396 handle_value = gattsEventP->params.authorize_request.request.read.handle;
vcoubard 542:884f95bf5351 397 break;
vcoubard 542:884f95bf5351 398 case BLE_GATTS_AUTHORIZE_TYPE_WRITE:
vcoubard 542:884f95bf5351 399 eventType = GattServerEvents::GATT_EVENT_WRITE_AUTHORIZATION_REQ;
vcoubard 542:884f95bf5351 400 handle_value = gattsEventP->params.authorize_request.request.write.handle;
vcoubard 542:884f95bf5351 401 break;
vcoubard 542:884f95bf5351 402 default:
vcoubard 542:884f95bf5351 403 return;
vcoubard 542:884f95bf5351 404 }
vcoubard 542:884f95bf5351 405 break;
vcoubard 542:884f95bf5351 406
vcoubard 542:884f95bf5351 407 default:
vcoubard 542:884f95bf5351 408 return;
vcoubard 542:884f95bf5351 409 }
vcoubard 542:884f95bf5351 410
vcoubard 542:884f95bf5351 411 int characteristicIndex = resolveValueHandleToCharIndex(handle_value);
vcoubard 542:884f95bf5351 412 if (characteristicIndex == -1) {
vcoubard 542:884f95bf5351 413 return;
vcoubard 542:884f95bf5351 414 }
vcoubard 542:884f95bf5351 415
vcoubard 542:884f95bf5351 416 /* Find index (charHandle) in the pool */
vcoubard 542:884f95bf5351 417 switch (eventType) {
vcoubard 542:884f95bf5351 418 case GattServerEvents::GATT_EVENT_DATA_WRITTEN: {
vcoubard 542:884f95bf5351 419 GattWriteCallbackParams cbParams = {
vcoubard 542:884f95bf5351 420 .connHandle = gattsEventP->conn_handle,
vcoubard 542:884f95bf5351 421 .handle = handle_value,
vcoubard 542:884f95bf5351 422 .writeOp = static_cast<GattWriteCallbackParams::WriteOp_t>(gattsEventP->params.write.op),
vcoubard 542:884f95bf5351 423 .offset = gattsEventP->params.write.offset,
vcoubard 542:884f95bf5351 424 .len = gattsEventP->params.write.len,
vcoubard 542:884f95bf5351 425 .data = gattsEventP->params.write.data
vcoubard 542:884f95bf5351 426 };
vcoubard 542:884f95bf5351 427 handleDataWrittenEvent(&cbParams);
vcoubard 542:884f95bf5351 428 break;
vcoubard 542:884f95bf5351 429 }
vcoubard 542:884f95bf5351 430 case GattServerEvents::GATT_EVENT_WRITE_AUTHORIZATION_REQ: {
vcoubard 542:884f95bf5351 431 GattWriteAuthCallbackParams cbParams = {
vcoubard 542:884f95bf5351 432 .connHandle = gattsEventP->conn_handle,
vcoubard 542:884f95bf5351 433 .handle = handle_value,
vcoubard 542:884f95bf5351 434 .offset = gattsEventP->params.authorize_request.request.write.offset,
vcoubard 542:884f95bf5351 435 .len = gattsEventP->params.authorize_request.request.write.len,
vcoubard 542:884f95bf5351 436 .data = gattsEventP->params.authorize_request.request.write.data,
vcoubard 542:884f95bf5351 437 .authorizationReply = AUTH_CALLBACK_REPLY_SUCCESS /* the callback handler must leave this member
vcoubard 542:884f95bf5351 438 * set to AUTH_CALLBACK_REPLY_SUCCESS if the client
vcoubard 542:884f95bf5351 439 * request is to proceed. */
vcoubard 542:884f95bf5351 440 };
vcoubard 542:884f95bf5351 441 ble_gatts_rw_authorize_reply_params_t reply = {
vcoubard 542:884f95bf5351 442 .type = BLE_GATTS_AUTHORIZE_TYPE_WRITE,
vcoubard 542:884f95bf5351 443 .params = {
vcoubard 542:884f95bf5351 444 .write = {
vcoubard 542:884f95bf5351 445 .gatt_status = p_characteristics[characteristicIndex]->authorizeWrite(&cbParams)
vcoubard 542:884f95bf5351 446 }
vcoubard 542:884f95bf5351 447 }
vcoubard 542:884f95bf5351 448 };
vcoubard 542:884f95bf5351 449 sd_ble_gatts_rw_authorize_reply(gattsEventP->conn_handle, &reply);
vcoubard 542:884f95bf5351 450
vcoubard 542:884f95bf5351 451 /*
vcoubard 542:884f95bf5351 452 * If write-authorization is enabled for a characteristic,
vcoubard 542:884f95bf5351 453 * AUTHORIZATION_REQ event (if replied with true) is *not*
vcoubard 542:884f95bf5351 454 * followed by another DATA_WRITTEN event; so we still need
vcoubard 542:884f95bf5351 455 * to invoke handleDataWritten(), much the same as we would
vcoubard 542:884f95bf5351 456 * have done if write-authorization had not been enabled.
vcoubard 542:884f95bf5351 457 */
vcoubard 542:884f95bf5351 458 if (reply.params.write.gatt_status == BLE_GATT_STATUS_SUCCESS) {
vcoubard 542:884f95bf5351 459 GattWriteCallbackParams cbParams = {
vcoubard 542:884f95bf5351 460 .connHandle = gattsEventP->conn_handle,
vcoubard 542:884f95bf5351 461 .handle = handle_value,
vcoubard 542:884f95bf5351 462 .writeOp = static_cast<GattWriteCallbackParams::WriteOp_t>(gattsEventP->params.authorize_request.request.write.op),
vcoubard 542:884f95bf5351 463 .offset = gattsEventP->params.authorize_request.request.write.offset,
vcoubard 542:884f95bf5351 464 .len = gattsEventP->params.authorize_request.request.write.len,
vcoubard 542:884f95bf5351 465 .data = gattsEventP->params.authorize_request.request.write.data,
vcoubard 542:884f95bf5351 466 };
vcoubard 542:884f95bf5351 467 handleDataWrittenEvent(&cbParams);
vcoubard 542:884f95bf5351 468 }
vcoubard 542:884f95bf5351 469 break;
vcoubard 542:884f95bf5351 470 }
vcoubard 542:884f95bf5351 471 case GattServerEvents::GATT_EVENT_READ_AUTHORIZATION_REQ: {
vcoubard 542:884f95bf5351 472 GattReadAuthCallbackParams cbParams = {
vcoubard 542:884f95bf5351 473 .connHandle = gattsEventP->conn_handle,
vcoubard 542:884f95bf5351 474 .handle = handle_value,
vcoubard 542:884f95bf5351 475 .offset = gattsEventP->params.authorize_request.request.read.offset,
vcoubard 542:884f95bf5351 476 .len = 0,
vcoubard 542:884f95bf5351 477 .data = NULL,
vcoubard 542:884f95bf5351 478 .authorizationReply = AUTH_CALLBACK_REPLY_SUCCESS /* the callback handler must leave this member
vcoubard 542:884f95bf5351 479 * set to AUTH_CALLBACK_REPLY_SUCCESS if the client
vcoubard 542:884f95bf5351 480 * request is to proceed. */
vcoubard 542:884f95bf5351 481 };
vcoubard 542:884f95bf5351 482
vcoubard 542:884f95bf5351 483 ble_gatts_rw_authorize_reply_params_t reply = {
vcoubard 542:884f95bf5351 484 .type = BLE_GATTS_AUTHORIZE_TYPE_READ,
vcoubard 542:884f95bf5351 485 .params = {
vcoubard 542:884f95bf5351 486 .read = {
vcoubard 542:884f95bf5351 487 .gatt_status = p_characteristics[characteristicIndex]->authorizeRead(&cbParams)
vcoubard 542:884f95bf5351 488 }
vcoubard 542:884f95bf5351 489 }
vcoubard 542:884f95bf5351 490 };
vcoubard 542:884f95bf5351 491
vcoubard 542:884f95bf5351 492 if (cbParams.authorizationReply == BLE_GATT_STATUS_SUCCESS) {
vcoubard 542:884f95bf5351 493 if (cbParams.data != NULL) {
vcoubard 542:884f95bf5351 494 reply.params.read.update = 1;
vcoubard 542:884f95bf5351 495 reply.params.read.offset = cbParams.offset;
vcoubard 542:884f95bf5351 496 reply.params.read.len = cbParams.len;
vcoubard 542:884f95bf5351 497 reply.params.read.p_data = cbParams.data;
vcoubard 542:884f95bf5351 498 }
vcoubard 542:884f95bf5351 499 }
vcoubard 542:884f95bf5351 500
vcoubard 542:884f95bf5351 501 sd_ble_gatts_rw_authorize_reply(gattsEventP->conn_handle, &reply);
vcoubard 542:884f95bf5351 502 break;
vcoubard 542:884f95bf5351 503 }
vcoubard 542:884f95bf5351 504
vcoubard 542:884f95bf5351 505 default:
vcoubard 542:884f95bf5351 506 handleEvent(eventType, handle_value);
vcoubard 542:884f95bf5351 507 break;
vcoubard 542:884f95bf5351 508 }
rgrover1 389:db85a09c27ef 509 }