To get started with Seeed Tiny BLE, include detecting motion, button and battery level.

Dependencies:   BLE_API eMPL_MPU6050 mbed nRF51822

Committer:
yihui
Date:
Thu Nov 05 02:46:37 2015 +0000
Revision:
2:b61ddbb8528e
Parent:
1:fc2f9d636751
able to recover from i2c bus fault

Who changed what in which revision?

UserRevisionLine numberNew contents of line
yihui 1:fc2f9d636751 1 /* mbed Microcontroller Library
yihui 1:fc2f9d636751 2 * Copyright (c) 2006-2013 ARM Limited
yihui 1:fc2f9d636751 3 *
yihui 1:fc2f9d636751 4 * Licensed under the Apache License, Version 2.0 (the "License");
yihui 1:fc2f9d636751 5 * you may not use this file except in compliance with the License.
yihui 1:fc2f9d636751 6 * You may obtain a copy of the License at
yihui 1:fc2f9d636751 7 *
yihui 1:fc2f9d636751 8 * http://www.apache.org/licenses/LICENSE-2.0
yihui 1:fc2f9d636751 9 *
yihui 1:fc2f9d636751 10 * Unless required by applicable law or agreed to in writing, software
yihui 1:fc2f9d636751 11 * distributed under the License is distributed on an "AS IS" BASIS,
yihui 1:fc2f9d636751 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
yihui 1:fc2f9d636751 13 * See the License for the specific language governing permissions and
yihui 1:fc2f9d636751 14 * limitations under the License.
yihui 1:fc2f9d636751 15 */
yihui 1:fc2f9d636751 16
yihui 1:fc2f9d636751 17 #include "nRF51GattServer.h"
yihui 1:fc2f9d636751 18 #include "mbed.h"
yihui 1:fc2f9d636751 19
yihui 1:fc2f9d636751 20 #include "common/common.h"
yihui 1:fc2f9d636751 21 #include "btle/custom/custom_helper.h"
yihui 1:fc2f9d636751 22
yihui 1:fc2f9d636751 23 #include "nRF51Gap.h"
yihui 1:fc2f9d636751 24
yihui 1:fc2f9d636751 25 /**************************************************************************/
yihui 1:fc2f9d636751 26 /*!
yihui 1:fc2f9d636751 27 @brief Adds a new service to the GATT table on the peripheral
yihui 1:fc2f9d636751 28
yihui 1:fc2f9d636751 29 @returns ble_error_t
yihui 1:fc2f9d636751 30
yihui 1:fc2f9d636751 31 @retval BLE_ERROR_NONE
yihui 1:fc2f9d636751 32 Everything executed properly
yihui 1:fc2f9d636751 33
yihui 1:fc2f9d636751 34 @section EXAMPLE
yihui 1:fc2f9d636751 35
yihui 1:fc2f9d636751 36 @code
yihui 1:fc2f9d636751 37
yihui 1:fc2f9d636751 38 @endcode
yihui 1:fc2f9d636751 39 */
yihui 1:fc2f9d636751 40 /**************************************************************************/
yihui 1:fc2f9d636751 41 ble_error_t nRF51GattServer::addService(GattService &service)
yihui 1:fc2f9d636751 42 {
yihui 1:fc2f9d636751 43 /* ToDo: Make sure we don't overflow the array, etc. */
yihui 1:fc2f9d636751 44 /* ToDo: Make sure this service UUID doesn't already exist (?) */
yihui 1:fc2f9d636751 45 /* ToDo: Basic validation */
yihui 1:fc2f9d636751 46
yihui 1:fc2f9d636751 47 /* Add the service to the nRF51 */
yihui 1:fc2f9d636751 48 ble_uuid_t nordicUUID;
yihui 1:fc2f9d636751 49 nordicUUID = custom_convert_to_nordic_uuid(service.getUUID());
yihui 1:fc2f9d636751 50
yihui 1:fc2f9d636751 51 uint16_t serviceHandle;
yihui 1:fc2f9d636751 52 ASSERT( ERROR_NONE ==
yihui 1:fc2f9d636751 53 sd_ble_gatts_service_add(BLE_GATTS_SRVC_TYPE_PRIMARY,
yihui 1:fc2f9d636751 54 &nordicUUID,
yihui 1:fc2f9d636751 55 &serviceHandle),
yihui 1:fc2f9d636751 56 BLE_ERROR_PARAM_OUT_OF_RANGE );
yihui 1:fc2f9d636751 57 service.setHandle(serviceHandle);
yihui 1:fc2f9d636751 58
yihui 1:fc2f9d636751 59 /* Add characteristics to the service */
yihui 1:fc2f9d636751 60 for (uint8_t i = 0; i < service.getCharacteristicCount(); i++) {
yihui 1:fc2f9d636751 61 GattCharacteristic *p_char = service.getCharacteristic(i);
yihui 1:fc2f9d636751 62
yihui 1:fc2f9d636751 63 /* Skip any incompletely defined, read-only characteristics. */
yihui 1:fc2f9d636751 64 if ((p_char->getValueAttribute().getValuePtr() == NULL) &&
yihui 1:fc2f9d636751 65 (p_char->getValueAttribute().getInitialLength() == 0) &&
yihui 1:fc2f9d636751 66 (p_char->getProperties() == GattCharacteristic::BLE_GATT_CHAR_PROPERTIES_READ)) {
yihui 1:fc2f9d636751 67 continue;
yihui 1:fc2f9d636751 68 }
yihui 1:fc2f9d636751 69
yihui 1:fc2f9d636751 70 nordicUUID = custom_convert_to_nordic_uuid(p_char->getValueAttribute().getUUID());
yihui 1:fc2f9d636751 71
yihui 1:fc2f9d636751 72 ASSERT ( ERROR_NONE ==
yihui 1:fc2f9d636751 73 custom_add_in_characteristic(BLE_GATT_HANDLE_INVALID,
yihui 1:fc2f9d636751 74 &nordicUUID,
yihui 1:fc2f9d636751 75 p_char->getProperties(),
yihui 1:fc2f9d636751 76 p_char->getValueAttribute().getValuePtr(),
yihui 1:fc2f9d636751 77 p_char->getValueAttribute().getInitialLength(),
yihui 1:fc2f9d636751 78 p_char->getValueAttribute().getMaxLength(),
yihui 1:fc2f9d636751 79 p_char->isReadAuthorizationEnabled(),
yihui 1:fc2f9d636751 80 p_char->isWriteAuthorizationEnabled(),
yihui 1:fc2f9d636751 81 &nrfCharacteristicHandles[characteristicCount]),
yihui 1:fc2f9d636751 82 BLE_ERROR_PARAM_OUT_OF_RANGE );
yihui 1:fc2f9d636751 83
yihui 1:fc2f9d636751 84 /* Update the characteristic handle */
yihui 1:fc2f9d636751 85 uint16_t charHandle = characteristicCount;
yihui 1:fc2f9d636751 86 p_characteristics[characteristicCount++] = p_char;
yihui 1:fc2f9d636751 87
yihui 1:fc2f9d636751 88 p_char->getValueAttribute().setHandle(charHandle);
yihui 1:fc2f9d636751 89
yihui 1:fc2f9d636751 90 /* Add optional descriptors if any */
yihui 1:fc2f9d636751 91 /* ToDo: Make sure we don't overflow the array */
yihui 1:fc2f9d636751 92 for (uint8_t j = 0; j < p_char->getDescriptorCount(); j++) {
yihui 1:fc2f9d636751 93 GattAttribute *p_desc = p_char->getDescriptor(j);
yihui 1:fc2f9d636751 94
yihui 1:fc2f9d636751 95 nordicUUID = custom_convert_to_nordic_uuid(p_desc->getUUID());
yihui 1:fc2f9d636751 96
yihui 1:fc2f9d636751 97 ASSERT ( ERROR_NONE ==
yihui 1:fc2f9d636751 98 custom_add_in_descriptor(BLE_GATT_HANDLE_INVALID,
yihui 1:fc2f9d636751 99 &nordicUUID,
yihui 1:fc2f9d636751 100 p_desc->getValuePtr(),
yihui 1:fc2f9d636751 101 p_desc->getInitialLength(),
yihui 1:fc2f9d636751 102 p_desc->getMaxLength(),
yihui 1:fc2f9d636751 103 &nrfDescriptorHandles[descriptorCount]),
yihui 1:fc2f9d636751 104 BLE_ERROR_PARAM_OUT_OF_RANGE );
yihui 1:fc2f9d636751 105
yihui 1:fc2f9d636751 106 uint16_t descHandle = descriptorCount;
yihui 1:fc2f9d636751 107 p_descriptors[descriptorCount++] = p_desc;
yihui 1:fc2f9d636751 108 p_desc->setHandle(descHandle);
yihui 1:fc2f9d636751 109 }
yihui 1:fc2f9d636751 110 }
yihui 1:fc2f9d636751 111
yihui 1:fc2f9d636751 112 serviceCount++;
yihui 1:fc2f9d636751 113
yihui 1:fc2f9d636751 114 return BLE_ERROR_NONE;
yihui 1:fc2f9d636751 115 }
yihui 1:fc2f9d636751 116
yihui 1:fc2f9d636751 117 /**************************************************************************/
yihui 1:fc2f9d636751 118 /*!
yihui 1:fc2f9d636751 119 @brief Reads the value of a characteristic, based on the service
yihui 1:fc2f9d636751 120 and characteristic index fields
yihui 1:fc2f9d636751 121
yihui 1:fc2f9d636751 122 @param[in] charHandle
yihui 1:fc2f9d636751 123 The handle of the GattCharacteristic to read from
yihui 1:fc2f9d636751 124 @param[in] buffer
yihui 1:fc2f9d636751 125 Buffer to hold the the characteristic's value
yihui 1:fc2f9d636751 126 (raw byte array in LSB format)
yihui 1:fc2f9d636751 127 @param[in] len
yihui 1:fc2f9d636751 128 The number of bytes read into the buffer
yihui 1:fc2f9d636751 129
yihui 1:fc2f9d636751 130 @returns ble_error_t
yihui 1:fc2f9d636751 131
yihui 1:fc2f9d636751 132 @retval BLE_ERROR_NONE
yihui 1:fc2f9d636751 133 Everything executed properly
yihui 1:fc2f9d636751 134
yihui 1:fc2f9d636751 135 @section EXAMPLE
yihui 1:fc2f9d636751 136
yihui 1:fc2f9d636751 137 @code
yihui 1:fc2f9d636751 138
yihui 1:fc2f9d636751 139 @endcode
yihui 1:fc2f9d636751 140 */
yihui 1:fc2f9d636751 141 /**************************************************************************/
yihui 1:fc2f9d636751 142 ble_error_t nRF51GattServer::readValue(GattAttribute::Handle_t charHandle, uint8_t buffer[], uint16_t *const lengthP)
yihui 1:fc2f9d636751 143 {
yihui 1:fc2f9d636751 144 ASSERT( ERROR_NONE ==
yihui 1:fc2f9d636751 145 sd_ble_gatts_value_get(nrfCharacteristicHandles[charHandle].value_handle, 0, lengthP, buffer),
yihui 1:fc2f9d636751 146 BLE_ERROR_PARAM_OUT_OF_RANGE);
yihui 1:fc2f9d636751 147
yihui 1:fc2f9d636751 148 return BLE_ERROR_NONE;
yihui 1:fc2f9d636751 149 }
yihui 1:fc2f9d636751 150
yihui 1:fc2f9d636751 151 /**************************************************************************/
yihui 1:fc2f9d636751 152 /*!
yihui 1:fc2f9d636751 153 @brief Updates the value of a characteristic, based on the service
yihui 1:fc2f9d636751 154 and characteristic index fields
yihui 1:fc2f9d636751 155
yihui 1:fc2f9d636751 156 @param[in] charHandle
yihui 1:fc2f9d636751 157 The handle of the GattCharacteristic to write to
yihui 1:fc2f9d636751 158 @param[in] buffer
yihui 1:fc2f9d636751 159 Data to use when updating the characteristic's value
yihui 1:fc2f9d636751 160 (raw byte array in LSB format)
yihui 1:fc2f9d636751 161 @param[in] len
yihui 1:fc2f9d636751 162 The number of bytes in buffer
yihui 1:fc2f9d636751 163
yihui 1:fc2f9d636751 164 @returns ble_error_t
yihui 1:fc2f9d636751 165
yihui 1:fc2f9d636751 166 @retval BLE_ERROR_NONE
yihui 1:fc2f9d636751 167 Everything executed properly
yihui 1:fc2f9d636751 168
yihui 1:fc2f9d636751 169 @section EXAMPLE
yihui 1:fc2f9d636751 170
yihui 1:fc2f9d636751 171 @code
yihui 1:fc2f9d636751 172
yihui 1:fc2f9d636751 173 @endcode
yihui 1:fc2f9d636751 174 */
yihui 1:fc2f9d636751 175 /**************************************************************************/
yihui 1:fc2f9d636751 176 ble_error_t nRF51GattServer::updateValue(GattAttribute::Handle_t charHandle, const uint8_t buffer[], uint16_t len, bool localOnly)
yihui 1:fc2f9d636751 177 {
yihui 1:fc2f9d636751 178 uint16_t gapConnectionHandle = nRF51Gap::getInstance().getConnectionHandle();
yihui 1:fc2f9d636751 179 ble_error_t returnValue = BLE_ERROR_NONE;
yihui 1:fc2f9d636751 180
yihui 1:fc2f9d636751 181 if (localOnly) {
yihui 1:fc2f9d636751 182 /* Only update locally regardless of notify/indicate */
yihui 1:fc2f9d636751 183 ASSERT_INT( ERROR_NONE,
yihui 1:fc2f9d636751 184 sd_ble_gatts_value_set(nrfCharacteristicHandles[charHandle].value_handle, 0, &len, buffer),
yihui 1:fc2f9d636751 185 BLE_ERROR_PARAM_OUT_OF_RANGE );
yihui 1:fc2f9d636751 186 return BLE_ERROR_NONE;
yihui 1:fc2f9d636751 187 }
yihui 1:fc2f9d636751 188
yihui 1:fc2f9d636751 189 if ((p_characteristics[charHandle]->getProperties() &
yihui 1:fc2f9d636751 190 (GattCharacteristic::BLE_GATT_CHAR_PROPERTIES_INDICATE |
yihui 1:fc2f9d636751 191 GattCharacteristic::BLE_GATT_CHAR_PROPERTIES_NOTIFY)) &&
yihui 1:fc2f9d636751 192 (gapConnectionHandle != BLE_CONN_HANDLE_INVALID)) {
yihui 1:fc2f9d636751 193 /* HVX update for the characteristic value */
yihui 1:fc2f9d636751 194 ble_gatts_hvx_params_t hvx_params;
yihui 1:fc2f9d636751 195
yihui 1:fc2f9d636751 196 hvx_params.handle = nrfCharacteristicHandles[charHandle].value_handle;
yihui 1:fc2f9d636751 197 hvx_params.type =
yihui 1:fc2f9d636751 198 (p_characteristics[charHandle]->getProperties() &
yihui 1:fc2f9d636751 199 GattCharacteristic::BLE_GATT_CHAR_PROPERTIES_NOTIFY) ?
yihui 1:fc2f9d636751 200 BLE_GATT_HVX_NOTIFICATION : BLE_GATT_HVX_INDICATION;
yihui 1:fc2f9d636751 201 hvx_params.offset = 0;
yihui 1:fc2f9d636751 202 hvx_params.p_data = const_cast<uint8_t *>(buffer);
yihui 1:fc2f9d636751 203 hvx_params.p_len = &len;
yihui 1:fc2f9d636751 204
yihui 1:fc2f9d636751 205 error_t error = (error_t) sd_ble_gatts_hvx(gapConnectionHandle, &hvx_params);
yihui 1:fc2f9d636751 206
yihui 1:fc2f9d636751 207 /* ERROR_INVALID_STATE, ERROR_BUSY, ERROR_GATTS_SYS_ATTR_MISSING and
yihui 1:fc2f9d636751 208 *ERROR_NO_TX_BUFFERS the ATT table has been updated. */
yihui 1:fc2f9d636751 209 if ((error != ERROR_NONE) && (error != ERROR_INVALID_STATE) &&
yihui 1:fc2f9d636751 210 (error != ERROR_BLE_NO_TX_BUFFERS) && (error != ERROR_BUSY) &&
yihui 1:fc2f9d636751 211 (error != ERROR_BLEGATTS_SYS_ATTR_MISSING)) {
yihui 1:fc2f9d636751 212 ASSERT_INT( ERROR_NONE,
yihui 1:fc2f9d636751 213 sd_ble_gatts_value_set(nrfCharacteristicHandles[charHandle].value_handle, 0, &len, buffer),
yihui 1:fc2f9d636751 214 BLE_ERROR_PARAM_OUT_OF_RANGE );
yihui 1:fc2f9d636751 215 }
yihui 1:fc2f9d636751 216
yihui 1:fc2f9d636751 217 /* Notifications consume application buffers. The return value can
yihui 1:fc2f9d636751 218 be used for resending notifications.
yihui 1:fc2f9d636751 219 */
yihui 1:fc2f9d636751 220 if (error != ERROR_NONE) {
yihui 1:fc2f9d636751 221 returnValue = BLE_STACK_BUSY;
yihui 1:fc2f9d636751 222 }
yihui 1:fc2f9d636751 223 } else {
yihui 1:fc2f9d636751 224 ASSERT_INT( ERROR_NONE,
yihui 1:fc2f9d636751 225 sd_ble_gatts_value_set(nrfCharacteristicHandles[charHandle].value_handle, 0, &len, buffer),
yihui 1:fc2f9d636751 226 BLE_ERROR_PARAM_OUT_OF_RANGE );
yihui 1:fc2f9d636751 227 }
yihui 1:fc2f9d636751 228
yihui 1:fc2f9d636751 229 return returnValue;
yihui 1:fc2f9d636751 230 }
yihui 1:fc2f9d636751 231
yihui 1:fc2f9d636751 232 /**************************************************************************/
yihui 1:fc2f9d636751 233 /*!
yihui 1:fc2f9d636751 234 @brief Callback handler for events getting pushed up from the SD
yihui 1:fc2f9d636751 235 */
yihui 1:fc2f9d636751 236 /**************************************************************************/
yihui 1:fc2f9d636751 237 void nRF51GattServer::hwCallback(ble_evt_t *p_ble_evt)
yihui 1:fc2f9d636751 238 {
yihui 1:fc2f9d636751 239 uint16_t handle_value;
yihui 1:fc2f9d636751 240 GattServerEvents::gattEvent_t eventType;
yihui 1:fc2f9d636751 241 const ble_gatts_evt_t *gattsEventP = &p_ble_evt->evt.gatts_evt;
yihui 1:fc2f9d636751 242
yihui 1:fc2f9d636751 243 switch (p_ble_evt->header.evt_id) {
yihui 1:fc2f9d636751 244 case BLE_GATTS_EVT_WRITE:
yihui 1:fc2f9d636751 245 /* There are 2 use case here: Values being updated & CCCD (indicate/notify) enabled */
yihui 1:fc2f9d636751 246
yihui 1:fc2f9d636751 247 /* 1.) Handle CCCD changes */
yihui 1:fc2f9d636751 248 handle_value = gattsEventP->params.write.handle;
yihui 1:fc2f9d636751 249 for (uint8_t i = 0; i<characteristicCount; i++) {
yihui 1:fc2f9d636751 250 if ((p_characteristics[i]->getProperties() & (GattCharacteristic::BLE_GATT_CHAR_PROPERTIES_INDICATE | GattCharacteristic::BLE_GATT_CHAR_PROPERTIES_NOTIFY)) &&
yihui 1:fc2f9d636751 251 (nrfCharacteristicHandles[i].cccd_handle == handle_value)) {
yihui 1:fc2f9d636751 252 uint16_t cccd_value =
yihui 1:fc2f9d636751 253 (gattsEventP->params.write.data[1] << 8) |
yihui 1:fc2f9d636751 254 gattsEventP->params.write.data[0]; /* Little Endian but M0 may be mis-aligned */
yihui 1:fc2f9d636751 255
yihui 1:fc2f9d636751 256 if (((p_characteristics[i]->getProperties() & GattCharacteristic::BLE_GATT_CHAR_PROPERTIES_INDICATE) && (cccd_value & BLE_GATT_HVX_INDICATION)) ||
yihui 1:fc2f9d636751 257 ((p_characteristics[i]->getProperties() & GattCharacteristic::BLE_GATT_CHAR_PROPERTIES_NOTIFY) && (cccd_value & BLE_GATT_HVX_NOTIFICATION))) {
yihui 1:fc2f9d636751 258 eventType = GattServerEvents::GATT_EVENT_UPDATES_ENABLED;
yihui 1:fc2f9d636751 259 } else {
yihui 1:fc2f9d636751 260 eventType = GattServerEvents::GATT_EVENT_UPDATES_DISABLED;
yihui 1:fc2f9d636751 261 }
yihui 1:fc2f9d636751 262
yihui 1:fc2f9d636751 263 handleEvent(eventType, i);
yihui 1:fc2f9d636751 264 return;
yihui 1:fc2f9d636751 265 }
yihui 1:fc2f9d636751 266 }
yihui 1:fc2f9d636751 267
yihui 1:fc2f9d636751 268 /* 2.) Changes to the characteristic value will be handled with other events below */
yihui 1:fc2f9d636751 269 eventType = GattServerEvents::GATT_EVENT_DATA_WRITTEN;
yihui 1:fc2f9d636751 270 break;
yihui 1:fc2f9d636751 271
yihui 1:fc2f9d636751 272 case BLE_GATTS_EVT_HVC:
yihui 1:fc2f9d636751 273 /* Indication confirmation received */
yihui 1:fc2f9d636751 274 eventType = GattServerEvents::GATT_EVENT_CONFIRMATION_RECEIVED;
yihui 1:fc2f9d636751 275 handle_value = gattsEventP->params.hvc.handle;
yihui 1:fc2f9d636751 276 break;
yihui 1:fc2f9d636751 277
yihui 1:fc2f9d636751 278 case BLE_EVT_TX_COMPLETE: {
yihui 1:fc2f9d636751 279 handleDataSentEvent(p_ble_evt->evt.common_evt.params.tx_complete.count);
yihui 1:fc2f9d636751 280 return;
yihui 1:fc2f9d636751 281 }
yihui 1:fc2f9d636751 282
yihui 1:fc2f9d636751 283 case BLE_GATTS_EVT_SYS_ATTR_MISSING:
yihui 1:fc2f9d636751 284 sd_ble_gatts_sys_attr_set(gattsEventP->conn_handle, NULL, 0);
yihui 1:fc2f9d636751 285 return;
yihui 1:fc2f9d636751 286
yihui 1:fc2f9d636751 287 case BLE_GATTS_EVT_RW_AUTHORIZE_REQUEST:
yihui 1:fc2f9d636751 288 switch (gattsEventP->params.authorize_request.type) {
yihui 1:fc2f9d636751 289 case BLE_GATTS_AUTHORIZE_TYPE_READ:
yihui 1:fc2f9d636751 290 eventType = GattServerEvents::GATT_EVENT_READ_AUTHORIZATION_REQ;
yihui 1:fc2f9d636751 291 handle_value = gattsEventP->params.authorize_request.request.read.handle;
yihui 1:fc2f9d636751 292 break;
yihui 1:fc2f9d636751 293 case BLE_GATTS_AUTHORIZE_TYPE_WRITE:
yihui 1:fc2f9d636751 294 eventType = GattServerEvents::GATT_EVENT_WRITE_AUTHORIZATION_REQ;
yihui 1:fc2f9d636751 295 handle_value = gattsEventP->params.authorize_request.request.write.handle;
yihui 1:fc2f9d636751 296 break;
yihui 1:fc2f9d636751 297 default:
yihui 1:fc2f9d636751 298 return;
yihui 1:fc2f9d636751 299 }
yihui 1:fc2f9d636751 300 break;
yihui 1:fc2f9d636751 301
yihui 1:fc2f9d636751 302 default:
yihui 1:fc2f9d636751 303 return;
yihui 1:fc2f9d636751 304 }
yihui 1:fc2f9d636751 305
yihui 1:fc2f9d636751 306 /* Find index (charHandle) in the pool */
yihui 1:fc2f9d636751 307 for (uint8_t i = 0; i < characteristicCount; i++) {
yihui 1:fc2f9d636751 308 if (nrfCharacteristicHandles[i].value_handle == handle_value) {
yihui 1:fc2f9d636751 309 switch (eventType) {
yihui 1:fc2f9d636751 310 case GattServerEvents::GATT_EVENT_DATA_WRITTEN: {
yihui 1:fc2f9d636751 311 GattCharacteristicWriteCBParams cbParams = {
yihui 1:fc2f9d636751 312 .charHandle = i,
yihui 1:fc2f9d636751 313 .op = static_cast<GattCharacteristicWriteCBParams::Type>(gattsEventP->params.write.op),
yihui 1:fc2f9d636751 314 .offset = gattsEventP->params.write.offset,
yihui 1:fc2f9d636751 315 .len = gattsEventP->params.write.len,
yihui 1:fc2f9d636751 316 .data = gattsEventP->params.write.data
yihui 1:fc2f9d636751 317 };
yihui 1:fc2f9d636751 318 handleDataWrittenEvent(&cbParams);
yihui 1:fc2f9d636751 319 break;
yihui 1:fc2f9d636751 320 }
yihui 1:fc2f9d636751 321 case GattServerEvents::GATT_EVENT_WRITE_AUTHORIZATION_REQ: {
yihui 1:fc2f9d636751 322 GattCharacteristicWriteAuthCBParams cbParams = {
yihui 1:fc2f9d636751 323 .charHandle = i,
yihui 1:fc2f9d636751 324 .offset = gattsEventP->params.authorize_request.request.write.offset,
yihui 1:fc2f9d636751 325 .len = gattsEventP->params.authorize_request.request.write.len,
yihui 1:fc2f9d636751 326 .data = gattsEventP->params.authorize_request.request.write.data,
yihui 1:fc2f9d636751 327 };
yihui 1:fc2f9d636751 328 ble_gatts_rw_authorize_reply_params_t reply = {
yihui 1:fc2f9d636751 329 .type = BLE_GATTS_AUTHORIZE_TYPE_WRITE,
yihui 1:fc2f9d636751 330 .params = {
yihui 1:fc2f9d636751 331 .write = {
yihui 1:fc2f9d636751 332 .gatt_status = p_characteristics[i]->authorizeWrite(&cbParams)
yihui 1:fc2f9d636751 333 }
yihui 1:fc2f9d636751 334 }
yihui 1:fc2f9d636751 335 };
yihui 1:fc2f9d636751 336 sd_ble_gatts_rw_authorize_reply(gattsEventP->conn_handle, &reply);
yihui 1:fc2f9d636751 337
yihui 1:fc2f9d636751 338 /*
yihui 1:fc2f9d636751 339 * If write-authorization is enabled for a characteristic,
yihui 1:fc2f9d636751 340 * AUTHORIZATION_REQ event (if replied with true) is *not*
yihui 1:fc2f9d636751 341 * followed by another DATA_WRITTEN event; so we still need
yihui 1:fc2f9d636751 342 * to invoke handleDataWritten(), much the same as we would
yihui 1:fc2f9d636751 343 * have done if write-authorization had not been enabled.
yihui 1:fc2f9d636751 344 */
yihui 1:fc2f9d636751 345 if (reply.params.write.gatt_status == BLE_GATT_STATUS_SUCCESS) {
yihui 1:fc2f9d636751 346 GattCharacteristicWriteCBParams cbParams = {
yihui 1:fc2f9d636751 347 .charHandle = i,
yihui 1:fc2f9d636751 348 .op = static_cast<GattCharacteristicWriteCBParams::Type>(gattsEventP->params.authorize_request.request.write.op),
yihui 1:fc2f9d636751 349 .offset = gattsEventP->params.authorize_request.request.write.offset,
yihui 1:fc2f9d636751 350 .len = gattsEventP->params.authorize_request.request.write.len,
yihui 1:fc2f9d636751 351 .data = gattsEventP->params.authorize_request.request.write.data,
yihui 1:fc2f9d636751 352 };
yihui 1:fc2f9d636751 353 handleDataWrittenEvent(&cbParams);
yihui 1:fc2f9d636751 354 }
yihui 1:fc2f9d636751 355 break;
yihui 1:fc2f9d636751 356 }
yihui 1:fc2f9d636751 357 case GattServerEvents::GATT_EVENT_READ_AUTHORIZATION_REQ: {
yihui 1:fc2f9d636751 358 GattCharacteristicReadAuthCBParams cbParams = {
yihui 1:fc2f9d636751 359 .charHandle = i,
yihui 1:fc2f9d636751 360 .offset = gattsEventP->params.authorize_request.request.read.offset,
yihui 1:fc2f9d636751 361 .len = 0,
yihui 1:fc2f9d636751 362 .data = NULL
yihui 1:fc2f9d636751 363 };
yihui 1:fc2f9d636751 364
yihui 1:fc2f9d636751 365 ble_gatts_rw_authorize_reply_params_t reply = {
yihui 1:fc2f9d636751 366 .type = BLE_GATTS_AUTHORIZE_TYPE_READ,
yihui 1:fc2f9d636751 367 .params = {
yihui 1:fc2f9d636751 368 .read = {
yihui 1:fc2f9d636751 369 .gatt_status = p_characteristics[i]->authorizeRead(&cbParams)
yihui 1:fc2f9d636751 370 }
yihui 1:fc2f9d636751 371 }
yihui 1:fc2f9d636751 372 };
yihui 1:fc2f9d636751 373
yihui 1:fc2f9d636751 374 if (cbParams.authorizationReply == BLE_GATT_STATUS_SUCCESS) {
yihui 1:fc2f9d636751 375 if (cbParams.data != NULL) {
yihui 1:fc2f9d636751 376 reply.params.read.update = 1;
yihui 1:fc2f9d636751 377 reply.params.read.offset = cbParams.offset;
yihui 1:fc2f9d636751 378 reply.params.read.len = cbParams.len;
yihui 1:fc2f9d636751 379 reply.params.read.p_data = cbParams.data;
yihui 1:fc2f9d636751 380 }
yihui 1:fc2f9d636751 381 }
yihui 1:fc2f9d636751 382
yihui 1:fc2f9d636751 383 sd_ble_gatts_rw_authorize_reply(gattsEventP->conn_handle, &reply);
yihui 1:fc2f9d636751 384 break;
yihui 1:fc2f9d636751 385 }
yihui 1:fc2f9d636751 386
yihui 1:fc2f9d636751 387 default:
yihui 1:fc2f9d636751 388 handleEvent(eventType, i);
yihui 1:fc2f9d636751 389 break;
yihui 1:fc2f9d636751 390 }
yihui 1:fc2f9d636751 391 }
yihui 1:fc2f9d636751 392 }
yihui 1:fc2f9d636751 393 }
yihui 1:fc2f9d636751 394
yihui 1:fc2f9d636751 395 ble_error_t
yihui 1:fc2f9d636751 396 nRF51GattServer::initializeGATTDatabase(void)
yihui 1:fc2f9d636751 397 {
yihui 1:fc2f9d636751 398 /* Empty. Services are populated in the GattDatabase through addService(). */
yihui 1:fc2f9d636751 399 return BLE_ERROR_NONE;
yihui 1:fc2f9d636751 400 }