For with fix for disconnection notifications

Fork of nRF51822 by Nordic Semiconductor

Committer:
Rohit Grover
Date:
Thu May 29 08:24:36 2014 +0100
Revision:
11:6277845e1cc5
Parent:
8:2214f1df6a6a
Child:
12:e151f55035b8
serviceIDs should also go through the UUIDTable

Who changed what in which revision?

UserRevisionLine numberNew contents of line
bogdanm 0:eff01767de02 1 /* mbed Microcontroller Library
bogdanm 0:eff01767de02 2 * Copyright (c) 2006-2013 ARM Limited
bogdanm 0:eff01767de02 3 *
bogdanm 0:eff01767de02 4 * Licensed under the Apache License, Version 2.0 (the "License");
bogdanm 0:eff01767de02 5 * you may not use this file except in compliance with the License.
bogdanm 0:eff01767de02 6 * You may obtain a copy of the License at
bogdanm 0:eff01767de02 7 *
bogdanm 0:eff01767de02 8 * http://www.apache.org/licenses/LICENSE-2.0
bogdanm 0:eff01767de02 9 *
bogdanm 0:eff01767de02 10 * Unless required by applicable law or agreed to in writing, software
bogdanm 0:eff01767de02 11 * distributed under the License is distributed on an "AS IS" BASIS,
bogdanm 0:eff01767de02 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
bogdanm 0:eff01767de02 13 * See the License for the specific language governing permissions and
bogdanm 0:eff01767de02 14 * limitations under the License.
bogdanm 0:eff01767de02 15 */
Rohit Grover 6:bbb4357dc135 16
bogdanm 0:eff01767de02 17 #include "nRF51GattServer.h"
bogdanm 0:eff01767de02 18 #include "mbed.h"
bogdanm 0:eff01767de02 19
bogdanm 0:eff01767de02 20 #include "common/common.h"
bogdanm 0:eff01767de02 21 #include "btle/custom/custom_helper.h"
bogdanm 0:eff01767de02 22
mbed_official 2:49e7ee9e88ab 23 #include "nRF51Gap.h"
mbed_official 1:f84abedbf4fb 24
bogdanm 0:eff01767de02 25 /**************************************************************************/
bogdanm 0:eff01767de02 26 /*!
bogdanm 0:eff01767de02 27 @brief Adds a new service to the GATT table on the peripheral
Rohit Grover 6:bbb4357dc135 28
bogdanm 0:eff01767de02 29 @returns ble_error_t
Rohit Grover 6:bbb4357dc135 30
bogdanm 0:eff01767de02 31 @retval BLE_ERROR_NONE
bogdanm 0:eff01767de02 32 Everything executed properly
Rohit Grover 6:bbb4357dc135 33
bogdanm 0:eff01767de02 34 @section EXAMPLE
bogdanm 0:eff01767de02 35
bogdanm 0:eff01767de02 36 @code
bogdanm 0:eff01767de02 37
bogdanm 0:eff01767de02 38 @endcode
bogdanm 0:eff01767de02 39 */
bogdanm 0:eff01767de02 40 /**************************************************************************/
bogdanm 0:eff01767de02 41 ble_error_t nRF51GattServer::addService(GattService & service)
bogdanm 0:eff01767de02 42 {
bogdanm 0:eff01767de02 43 /* ToDo: Make sure we don't overflow the array, etc. */
bogdanm 0:eff01767de02 44 /* ToDo: Make sure this service UUID doesn't already exist (?) */
bogdanm 0:eff01767de02 45 /* ToDo: Basic validation */
Rohit Grover 6:bbb4357dc135 46
bogdanm 0:eff01767de02 47 /* Add the service to the nRF51 */
Rohit Grover 11:6277845e1cc5 48 ble_uuid_t nordicUUID;
Rohit Grover 11:6277845e1cc5 49 nordicUUID = custom_convert_to_transport_uuid(service.primaryServiceID);
Rohit Grover 6:bbb4357dc135 50 ASSERT( ERROR_NONE ==
Rohit Grover 6:bbb4357dc135 51 sd_ble_gatts_service_add(BLE_GATTS_SRVC_TYPE_PRIMARY,
Rohit Grover 11:6277845e1cc5 52 &nordicUUID,
Rohit Grover 6:bbb4357dc135 53 &service.handle),
Rohit Grover 6:bbb4357dc135 54 BLE_ERROR_PARAM_OUT_OF_RANGE );
bogdanm 0:eff01767de02 55
bogdanm 0:eff01767de02 56 /* Add characteristics to the service */
Rohit Grover 6:bbb4357dc135 57 for (uint8_t i = 0; i < service.characteristicCount; i++) {
Rohit Grover 6:bbb4357dc135 58 GattCharacteristic *p_char = service.characteristics[i];
bogdanm 0:eff01767de02 59
Rohit Grover 11:6277845e1cc5 60 nordicUUID = custom_convert_to_transport_uuid(p_char->uuid);
Rohit Grover 7:dd6465921aaa 61
Rohit Grover 6:bbb4357dc135 62 ASSERT ( ERROR_NONE ==
Rohit Grover 6:bbb4357dc135 63 custom_add_in_characteristic(service.handle,
Rohit Grover 11:6277845e1cc5 64 &nordicUUID,
Rohit Grover 6:bbb4357dc135 65 p_char->properties,
Rohit Grover 6:bbb4357dc135 66 NULL,
Rohit Grover 6:bbb4357dc135 67 p_char->lenMin,
Rohit Grover 6:bbb4357dc135 68 p_char->lenMax,
Rohit Grover 6:bbb4357dc135 69 &nrfCharacteristicHandles[
Rohit Grover 6:bbb4357dc135 70 characteristicCount]),
Rohit Grover 6:bbb4357dc135 71 BLE_ERROR_PARAM_OUT_OF_RANGE );
Rohit Grover 6:bbb4357dc135 72
Rohit Grover 6:bbb4357dc135 73 /* Update the characteristic handle */
Rohit Grover 6:bbb4357dc135 74 p_char->handle = characteristicCount;
Rohit Grover 6:bbb4357dc135 75 p_characteristics[characteristicCount++] = p_char;
bogdanm 0:eff01767de02 76 }
bogdanm 0:eff01767de02 77
bogdanm 0:eff01767de02 78 serviceCount++;
Rohit Grover 6:bbb4357dc135 79
bogdanm 0:eff01767de02 80 return BLE_ERROR_NONE;
bogdanm 0:eff01767de02 81 }
bogdanm 0:eff01767de02 82
bogdanm 0:eff01767de02 83 /**************************************************************************/
bogdanm 0:eff01767de02 84 /*!
bogdanm 0:eff01767de02 85 @brief Reads the value of a characteristic, based on the service
bogdanm 0:eff01767de02 86 and characteristic index fields
bogdanm 0:eff01767de02 87
bogdanm 0:eff01767de02 88 @param[in] charHandle
bogdanm 0:eff01767de02 89 The handle of the GattCharacteristic to read from
bogdanm 0:eff01767de02 90 @param[in] buffer
bogdanm 0:eff01767de02 91 Buffer to hold the the characteristic's value
bogdanm 0:eff01767de02 92 (raw byte array in LSB format)
bogdanm 0:eff01767de02 93 @param[in] len
bogdanm 0:eff01767de02 94 The number of bytes read into the buffer
Rohit Grover 6:bbb4357dc135 95
bogdanm 0:eff01767de02 96 @returns ble_error_t
Rohit Grover 6:bbb4357dc135 97
bogdanm 0:eff01767de02 98 @retval BLE_ERROR_NONE
bogdanm 0:eff01767de02 99 Everything executed properly
Rohit Grover 6:bbb4357dc135 100
bogdanm 0:eff01767de02 101 @section EXAMPLE
bogdanm 0:eff01767de02 102
bogdanm 0:eff01767de02 103 @code
bogdanm 0:eff01767de02 104
bogdanm 0:eff01767de02 105 @endcode
bogdanm 0:eff01767de02 106 */
bogdanm 0:eff01767de02 107 /**************************************************************************/
Rohit Grover 6:bbb4357dc135 108 ble_error_t nRF51GattServer::readValue(uint16_t charHandle,
Rohit Grover 6:bbb4357dc135 109 uint8_t buffer[],
Rohit Grover 6:bbb4357dc135 110 uint16_t len)
bogdanm 0:eff01767de02 111 {
Rohit Grover 6:bbb4357dc135 112 ASSERT( ERROR_NONE ==
Rohit Grover 6:bbb4357dc135 113 sd_ble_gatts_value_get(nrfCharacteristicHandles[charHandle].
Rohit Grover 6:bbb4357dc135 114 value_handle, 0,
Rohit Grover 6:bbb4357dc135 115 &len, buffer), BLE_ERROR_PARAM_OUT_OF_RANGE);
Rohit Grover 6:bbb4357dc135 116
bogdanm 0:eff01767de02 117 return BLE_ERROR_NONE;
bogdanm 0:eff01767de02 118 }
bogdanm 0:eff01767de02 119
bogdanm 0:eff01767de02 120 /**************************************************************************/
bogdanm 0:eff01767de02 121 /*!
bogdanm 0:eff01767de02 122 @brief Updates the value of a characteristic, based on the service
bogdanm 0:eff01767de02 123 and characteristic index fields
bogdanm 0:eff01767de02 124
bogdanm 0:eff01767de02 125 @param[in] charHandle
bogdanm 0:eff01767de02 126 The handle of the GattCharacteristic to write to
bogdanm 0:eff01767de02 127 @param[in] buffer
bogdanm 0:eff01767de02 128 Data to use when updating the characteristic's value
bogdanm 0:eff01767de02 129 (raw byte array in LSB format)
bogdanm 0:eff01767de02 130 @param[in] len
bogdanm 0:eff01767de02 131 The number of bytes in buffer
Rohit Grover 6:bbb4357dc135 132
bogdanm 0:eff01767de02 133 @returns ble_error_t
Rohit Grover 6:bbb4357dc135 134
bogdanm 0:eff01767de02 135 @retval BLE_ERROR_NONE
bogdanm 0:eff01767de02 136 Everything executed properly
Rohit Grover 6:bbb4357dc135 137
bogdanm 0:eff01767de02 138 @section EXAMPLE
bogdanm 0:eff01767de02 139
bogdanm 0:eff01767de02 140 @code
bogdanm 0:eff01767de02 141
bogdanm 0:eff01767de02 142 @endcode
bogdanm 0:eff01767de02 143 */
bogdanm 0:eff01767de02 144 /**************************************************************************/
Rohit Grover 6:bbb4357dc135 145 ble_error_t nRF51GattServer::updateValue(uint16_t charHandle,
Rohit Grover 6:bbb4357dc135 146 uint8_t buffer[],
Rohit Grover 6:bbb4357dc135 147 uint16_t len,
Rohit Grover 6:bbb4357dc135 148 bool localOnly)
bogdanm 0:eff01767de02 149 {
Rohit Grover 6:bbb4357dc135 150 uint16_t gapConnectionHandle =
Rohit Grover 6:bbb4357dc135 151 nRF51Gap::getInstance().getConnectionHandle();
Rohit Grover 6:bbb4357dc135 152
Rohit Grover 6:bbb4357dc135 153 if (localOnly) {
Rohit Grover 6:bbb4357dc135 154 /* Only update locally regardless of notify/indicate */
Rohit Grover 6:bbb4357dc135 155 ASSERT_INT( ERROR_NONE,
Rohit Grover 6:bbb4357dc135 156 sd_ble_gatts_value_set(nrfCharacteristicHandles[charHandle].
Rohit Grover 6:bbb4357dc135 157 value_handle,
Rohit Grover 6:bbb4357dc135 158 0,
Rohit Grover 6:bbb4357dc135 159 &len,
Rohit Grover 6:bbb4357dc135 160 buffer),
Rohit Grover 6:bbb4357dc135 161 BLE_ERROR_PARAM_OUT_OF_RANGE );
Rohit Grover 6:bbb4357dc135 162 }
Rohit Grover 6:bbb4357dc135 163
Rohit Grover 6:bbb4357dc135 164 if ((p_characteristics[charHandle]->properties &
Rohit Grover 6:bbb4357dc135 165 (GattCharacteristic::BLE_GATT_CHAR_PROPERTIES_INDICATE |
Rohit Grover 6:bbb4357dc135 166 GattCharacteristic::BLE_GATT_CHAR_PROPERTIES_NOTIFY)) &&
Rohit Grover 6:bbb4357dc135 167 (gapConnectionHandle != BLE_CONN_HANDLE_INVALID)) {
Rohit Grover 6:bbb4357dc135 168 /* HVX update for the characteristic value */
Rohit Grover 6:bbb4357dc135 169 ble_gatts_hvx_params_t hvx_params;
bogdanm 0:eff01767de02 170
Rohit Grover 6:bbb4357dc135 171 hvx_params.handle = nrfCharacteristicHandles[charHandle].value_handle;
Rohit Grover 6:bbb4357dc135 172 hvx_params.type =
Rohit Grover 6:bbb4357dc135 173 (p_characteristics[charHandle]->properties &
Rohit Grover 6:bbb4357dc135 174 GattCharacteristic::BLE_GATT_CHAR_PROPERTIES_NOTIFY) ?
Rohit Grover 6:bbb4357dc135 175 BLE_GATT_HVX_NOTIFICATION : BLE_GATT_HVX_INDICATION;
Rohit Grover 6:bbb4357dc135 176 hvx_params.offset = 0;
Rohit Grover 6:bbb4357dc135 177 hvx_params.p_data = buffer;
Rohit Grover 6:bbb4357dc135 178 hvx_params.p_len = &len;
bogdanm 0:eff01767de02 179
Rohit Grover 6:bbb4357dc135 180 error_t error = (error_t) sd_ble_gatts_hvx(gapConnectionHandle,
Rohit Grover 6:bbb4357dc135 181 &hvx_params);
bogdanm 0:eff01767de02 182
Rohit Grover 6:bbb4357dc135 183 /* ERROR_INVALID_STATE, ERROR_BUSY, ERROR_GATTS_SYS_ATTR_MISSING and
Rohit Grover 6:bbb4357dc135 184 *ERROR_NO_TX_BUFFERS the ATT table has been updated. */
Rohit Grover 6:bbb4357dc135 185 if ((error != ERROR_NONE) && (error != ERROR_INVALID_STATE) &&
Rohit Grover 6:bbb4357dc135 186 (error != ERROR_BLE_NO_TX_BUFFERS) && (error != ERROR_BUSY) &&
Rohit Grover 6:bbb4357dc135 187 (error != ERROR_BLEGATTS_SYS_ATTR_MISSING)) {
Rohit Grover 6:bbb4357dc135 188 ASSERT_INT( ERROR_NONE,
Rohit Grover 6:bbb4357dc135 189 sd_ble_gatts_value_set(nrfCharacteristicHandles[
Rohit Grover 6:bbb4357dc135 190 charHandle].
Rohit Grover 6:bbb4357dc135 191 value_handle,
Rohit Grover 6:bbb4357dc135 192 0,
Rohit Grover 6:bbb4357dc135 193 &len,
Rohit Grover 6:bbb4357dc135 194 buffer),
Rohit Grover 6:bbb4357dc135 195 BLE_ERROR_PARAM_OUT_OF_RANGE );
Rohit Grover 6:bbb4357dc135 196 }
Rohit Grover 6:bbb4357dc135 197 } else {
Rohit Grover 6:bbb4357dc135 198 ASSERT_INT( ERROR_NONE,
Rohit Grover 6:bbb4357dc135 199 sd_ble_gatts_value_set(nrfCharacteristicHandles[charHandle].
Rohit Grover 6:bbb4357dc135 200 value_handle,
Rohit Grover 6:bbb4357dc135 201 0,
Rohit Grover 6:bbb4357dc135 202 &len,
Rohit Grover 6:bbb4357dc135 203 buffer),
Rohit Grover 6:bbb4357dc135 204 BLE_ERROR_PARAM_OUT_OF_RANGE );
bogdanm 0:eff01767de02 205 }
Rohit Grover 6:bbb4357dc135 206
Rohit Grover 6:bbb4357dc135 207 return BLE_ERROR_NONE;
bogdanm 0:eff01767de02 208 }
bogdanm 0:eff01767de02 209
bogdanm 0:eff01767de02 210 /**************************************************************************/
bogdanm 0:eff01767de02 211 /*!
bogdanm 0:eff01767de02 212 @brief Callback handler for events getting pushed up from the SD
bogdanm 0:eff01767de02 213 */
bogdanm 0:eff01767de02 214 /**************************************************************************/
Rohit Grover 6:bbb4357dc135 215 void nRF51GattServer::hwCallback(ble_evt_t *p_ble_evt)
bogdanm 0:eff01767de02 216 {
Rohit Grover 6:bbb4357dc135 217 uint16_t handle_value;
Rohit Grover 6:bbb4357dc135 218 GattServerEvents::gattEvent_t event;
bogdanm 0:eff01767de02 219
Rohit Grover 6:bbb4357dc135 220 switch (p_ble_evt->header.evt_id) {
bogdanm 0:eff01767de02 221 case BLE_GATTS_EVT_WRITE:
Rohit Grover 6:bbb4357dc135 222 /* There are 2 use case here: Values being updated & CCCD
Rohit Grover 6:bbb4357dc135 223 *(indicate/notify) enabled */
Rohit Grover 6:bbb4357dc135 224
Rohit Grover 6:bbb4357dc135 225 /* 1.) Handle CCCD changes */
Rohit Grover 6:bbb4357dc135 226 handle_value = p_ble_evt->evt.gatts_evt.params.write.handle;
Rohit Grover 6:bbb4357dc135 227 for (uint8_t i = 0; i<characteristicCount; i++) {
Rohit Grover 6:bbb4357dc135 228 if ((p_characteristics[i]->properties &
Rohit Grover 6:bbb4357dc135 229 (GattCharacteristic::BLE_GATT_CHAR_PROPERTIES_INDICATE |
Rohit Grover 6:bbb4357dc135 230 GattCharacteristic::BLE_GATT_CHAR_PROPERTIES_NOTIFY)) &&
Rohit Grover 6:bbb4357dc135 231 (nrfCharacteristicHandles[i].cccd_handle == handle_value)) {
Rohit Grover 6:bbb4357dc135 232 uint16_t cccd_value =
Rohit Grover 6:bbb4357dc135 233 (p_ble_evt->evt.gatts_evt.params.write.data[1] <<
Rohit Grover 6:bbb4357dc135 234 8) | p_ble_evt->evt.gatts_evt.params.write.data[0]; /*
Rohit Grover 6:bbb4357dc135 235 * Little Endian but M0 may
Rohit Grover 6:bbb4357dc135 236 * be mis-aligned */
bogdanm 0:eff01767de02 237
Rohit Grover 6:bbb4357dc135 238 if (((p_characteristics[i]->properties &
Rohit Grover 6:bbb4357dc135 239 GattCharacteristic::BLE_GATT_CHAR_PROPERTIES_INDICATE) &&
Rohit Grover 6:bbb4357dc135 240 (cccd_value & BLE_GATT_HVX_INDICATION)) ||
Rohit Grover 6:bbb4357dc135 241 ((p_characteristics[i]->properties &
Rohit Grover 6:bbb4357dc135 242 GattCharacteristic::BLE_GATT_CHAR_PROPERTIES_NOTIFY) &&
Rohit Grover 6:bbb4357dc135 243 (cccd_value & BLE_GATT_HVX_NOTIFICATION))) {
Rohit Grover 6:bbb4357dc135 244 event = GattServerEvents::GATT_EVENT_UPDATES_ENABLED;
Rohit Grover 6:bbb4357dc135 245 } else {
Rohit Grover 6:bbb4357dc135 246 event = GattServerEvents::GATT_EVENT_UPDATES_DISABLED;
Rohit Grover 6:bbb4357dc135 247 }
bogdanm 0:eff01767de02 248
Rohit Grover 6:bbb4357dc135 249 handleEvent(event, i);
Rohit Grover 6:bbb4357dc135 250 return;
Rohit Grover 6:bbb4357dc135 251 }
bogdanm 0:eff01767de02 252 }
bogdanm 0:eff01767de02 253
Rohit Grover 6:bbb4357dc135 254 /* 2.) Changes to the characteristic value will be handled with other
Rohit Grover 6:bbb4357dc135 255 *events below */
Rohit Grover 6:bbb4357dc135 256 event = GattServerEvents::GATT_EVENT_DATA_WRITTEN;
Rohit Grover 6:bbb4357dc135 257 break;
bogdanm 0:eff01767de02 258
bogdanm 0:eff01767de02 259 case BLE_GATTS_EVT_HVC:
Rohit Grover 6:bbb4357dc135 260 /* Indication confirmation received */
Rohit Grover 6:bbb4357dc135 261 event = GattServerEvents::GATT_EVENT_CONFIRMATION_RECEIVED;
Rohit Grover 6:bbb4357dc135 262 handle_value = p_ble_evt->evt.gatts_evt.params.hvc.handle;
Rohit Grover 6:bbb4357dc135 263 break;
bogdanm 0:eff01767de02 264
Rohit Grover 6:bbb4357dc135 265 default:
Rohit Grover 6:bbb4357dc135 266 return;
Rohit Grover 6:bbb4357dc135 267 }
bogdanm 0:eff01767de02 268
Rohit Grover 6:bbb4357dc135 269 /* Find index (charHandle) in the pool */
Rohit Grover 6:bbb4357dc135 270 for (uint8_t i = 0; i<characteristicCount; i++) {
Rohit Grover 6:bbb4357dc135 271 if (nrfCharacteristicHandles[i].value_handle == handle_value) {
Rohit Grover 6:bbb4357dc135 272 handleEvent(event, i);
Rohit Grover 6:bbb4357dc135 273 break;
Rohit Grover 6:bbb4357dc135 274 }
bogdanm 0:eff01767de02 275 }
bogdanm 0:eff01767de02 276 }