Nordic stack and drivers for the mbed BLE API

Fork of nRF51822 by Nordic Semiconductor

Committer:
amithy
Date:
Fri Nov 10 01:00:06 2017 +0000
Revision:
639:5aeed2c29513
Parent:
638:c90ae1400bf2
for testing export

Who changed what in which revision?

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