Important changes to repositories hosted on mbed.com
Mbed hosted mercurial repositories are deprecated and are due to be permanently deleted in July 2026.
To keep a copy of this software download the repository Zip archive or clone locally using Mercurial.
It is also possible to export all your personal repositories from the account settings page.
Fork of nRF51822 by
TARGET_MCU_NRF51822/source/nRF5xGattServer.cpp@638:c90ae1400bf2, 2016-09-14 (annotated)
- Committer:
- Vincent Coubard
- Date:
- Wed Sep 14 14:39:43 2016 +0100
- Revision:
- 638:c90ae1400bf2
Sync with bdab10dc0f90748b6989c8b577771bb403ca6bd8 from ARMmbed/mbed-os.
Who changed what in which revision?
| User | Revision | Line number | New 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 | } |
