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
nRF51GattServer.cpp
00001 /* mbed Microcontroller Library 00002 * Copyright (c) 2006-2013 ARM Limited 00003 * 00004 * Licensed under the Apache License, Version 2.0 (the "License"); 00005 * you may not use this file except in compliance with the License. 00006 * You may obtain a copy of the License at 00007 * 00008 * http://www.apache.org/licenses/LICENSE-2.0 00009 * 00010 * Unless required by applicable law or agreed to in writing, software 00011 * distributed under the License is distributed on an "AS IS" BASIS, 00012 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 00013 * See the License for the specific language governing permissions and 00014 * limitations under the License. 00015 */ 00016 00017 #include "nRF51GattServer.h" 00018 #include "mbed.h" 00019 00020 #include "common/common.h " 00021 #include "btle/custom/custom_helper.h" 00022 00023 #include "nRF51Gap.h" 00024 00025 /**************************************************************************/ 00026 /*! 00027 @brief Adds a new service to the GATT table on the peripheral 00028 00029 @returns ble_error_t 00030 00031 @retval BLE_ERROR_NONE 00032 Everything executed properly 00033 00034 @section EXAMPLE 00035 00036 @code 00037 00038 @endcode 00039 */ 00040 /**************************************************************************/ 00041 ble_error_t nRF51GattServer::addService(GattService &service) 00042 { 00043 /* ToDo: Make sure we don't overflow the array, etc. */ 00044 /* ToDo: Make sure this service UUID doesn't already exist (?) */ 00045 /* ToDo: Basic validation */ 00046 00047 /* Add the service to the nRF51 */ 00048 ble_uuid_t nordicUUID; 00049 nordicUUID = custom_convert_to_nordic_uuid(service.getUUID()); 00050 00051 uint16_t serviceHandle; 00052 ASSERT( ERROR_NONE == 00053 sd_ble_gatts_service_add(BLE_GATTS_SRVC_TYPE_PRIMARY, 00054 &nordicUUID, 00055 &serviceHandle), 00056 BLE_ERROR_PARAM_OUT_OF_RANGE ); 00057 service.setHandle(serviceHandle); 00058 00059 /* Add characteristics to the service */ 00060 for (uint8_t i = 0; i < service.getCharacteristicCount(); i++) { 00061 GattCharacteristic *p_char = service.getCharacteristic(i); 00062 00063 /* Skip any incompletely defined, read-only characteristics. */ 00064 if ((p_char->getValueAttribute().getValuePtr() == NULL) && 00065 (p_char->getValueAttribute().getInitialLength() == 0) && 00066 (p_char->getProperties() == GattCharacteristic::BLE_GATT_CHAR_PROPERTIES_READ)) { 00067 continue; 00068 } 00069 00070 nordicUUID = custom_convert_to_nordic_uuid(p_char->getValueAttribute().getUUID()); 00071 00072 ASSERT ( ERROR_NONE == 00073 custom_add_in_characteristic(BLE_GATT_HANDLE_INVALID, 00074 &nordicUUID, 00075 p_char->getProperties(), 00076 p_char->getValueAttribute().getValuePtr(), 00077 p_char->getValueAttribute().getInitialLength(), 00078 p_char->getValueAttribute().getMaxLength(), 00079 p_char->isReadAuthorizationEnabled(), 00080 p_char->isWriteAuthorizationEnabled(), 00081 &nrfCharacteristicHandles[characteristicCount]), 00082 BLE_ERROR_PARAM_OUT_OF_RANGE ); 00083 00084 /* Update the characteristic handle */ 00085 uint16_t charHandle = characteristicCount; 00086 p_characteristics[characteristicCount++] = p_char; 00087 00088 p_char->getValueAttribute().setHandle(charHandle); 00089 00090 /* Add optional descriptors if any */ 00091 /* ToDo: Make sure we don't overflow the array */ 00092 for (uint8_t j = 0; j < p_char->getDescriptorCount(); j++) { 00093 GattAttribute *p_desc = p_char->getDescriptor(j); 00094 00095 nordicUUID = custom_convert_to_nordic_uuid(p_desc->getUUID()); 00096 00097 ASSERT ( ERROR_NONE == 00098 custom_add_in_descriptor(BLE_GATT_HANDLE_INVALID, 00099 &nordicUUID, 00100 p_desc->getValuePtr(), 00101 p_desc->getInitialLength(), 00102 p_desc->getMaxLength(), 00103 &nrfDescriptorHandles[descriptorCount]), 00104 BLE_ERROR_PARAM_OUT_OF_RANGE ); 00105 00106 uint16_t descHandle = descriptorCount; 00107 p_descriptors[descriptorCount++] = p_desc; 00108 p_desc->setHandle(descHandle); 00109 } 00110 } 00111 00112 serviceCount++; 00113 00114 return BLE_ERROR_NONE; 00115 } 00116 00117 /**************************************************************************/ 00118 /*! 00119 @brief Reads the value of a characteristic, based on the service 00120 and characteristic index fields 00121 00122 @param[in] charHandle 00123 The handle of the GattCharacteristic to read from 00124 @param[in] buffer 00125 Buffer to hold the the characteristic's value 00126 (raw byte array in LSB format) 00127 @param[in] len 00128 The number of bytes read into the buffer 00129 00130 @returns ble_error_t 00131 00132 @retval BLE_ERROR_NONE 00133 Everything executed properly 00134 00135 @section EXAMPLE 00136 00137 @code 00138 00139 @endcode 00140 */ 00141 /**************************************************************************/ 00142 ble_error_t nRF51GattServer::readValue(uint16_t charHandle, uint8_t buffer[], uint16_t *const lengthP) 00143 { 00144 ASSERT( ERROR_NONE == 00145 sd_ble_gatts_value_get(nrfCharacteristicHandles[charHandle].value_handle, 0, lengthP, buffer), 00146 BLE_ERROR_PARAM_OUT_OF_RANGE); 00147 00148 return BLE_ERROR_NONE; 00149 } 00150 00151 /**************************************************************************/ 00152 /*! 00153 @brief Updates the value of a characteristic, based on the service 00154 and characteristic index fields 00155 00156 @param[in] charHandle 00157 The handle of the GattCharacteristic to write to 00158 @param[in] buffer 00159 Data to use when updating the characteristic's value 00160 (raw byte array in LSB format) 00161 @param[in] len 00162 The number of bytes in buffer 00163 00164 @returns ble_error_t 00165 00166 @retval BLE_ERROR_NONE 00167 Everything executed properly 00168 00169 @section EXAMPLE 00170 00171 @code 00172 00173 @endcode 00174 */ 00175 /**************************************************************************/ 00176 ble_error_t nRF51GattServer::updateValue(uint16_t charHandle, uint8_t buffer[], uint16_t len, bool localOnly) 00177 { 00178 uint16_t gapConnectionHandle = nRF51Gap::getInstance().getConnectionHandle(); 00179 00180 if (localOnly) { 00181 /* Only update locally regardless of notify/indicate */ 00182 ASSERT_INT( ERROR_NONE, 00183 sd_ble_gatts_value_set(nrfCharacteristicHandles[charHandle].value_handle, 0, &len, buffer), 00184 BLE_ERROR_PARAM_OUT_OF_RANGE ); 00185 return BLE_ERROR_NONE; 00186 } 00187 00188 if ((p_characteristics[charHandle]->getProperties() & 00189 (GattCharacteristic::BLE_GATT_CHAR_PROPERTIES_INDICATE | 00190 GattCharacteristic::BLE_GATT_CHAR_PROPERTIES_NOTIFY)) && 00191 (gapConnectionHandle != BLE_CONN_HANDLE_INVALID)) { 00192 /* HVX update for the characteristic value */ 00193 ble_gatts_hvx_params_t hvx_params; 00194 00195 hvx_params.handle = nrfCharacteristicHandles[charHandle].value_handle; 00196 hvx_params.type = 00197 (p_characteristics[charHandle]->getProperties() & 00198 GattCharacteristic::BLE_GATT_CHAR_PROPERTIES_NOTIFY) ? 00199 BLE_GATT_HVX_NOTIFICATION : BLE_GATT_HVX_INDICATION; 00200 hvx_params.offset = 0; 00201 hvx_params.p_data = buffer; 00202 hvx_params.p_len = &len; 00203 00204 error_t error = (error_t) sd_ble_gatts_hvx(gapConnectionHandle, &hvx_params); 00205 00206 /* ERROR_INVALID_STATE, ERROR_BUSY, ERROR_GATTS_SYS_ATTR_MISSING and 00207 *ERROR_NO_TX_BUFFERS the ATT table has been updated. */ 00208 if ((error != ERROR_NONE) && (error != ERROR_INVALID_STATE) && 00209 (error != ERROR_BLE_NO_TX_BUFFERS) && (error != ERROR_BUSY) && 00210 (error != ERROR_BLEGATTS_SYS_ATTR_MISSING)) { 00211 ASSERT_INT( ERROR_NONE, 00212 sd_ble_gatts_value_set(nrfCharacteristicHandles[charHandle].value_handle, 0, &len, buffer), 00213 BLE_ERROR_PARAM_OUT_OF_RANGE ); 00214 } 00215 } else { 00216 ASSERT_INT( ERROR_NONE, 00217 sd_ble_gatts_value_set(nrfCharacteristicHandles[charHandle].value_handle, 0, &len, buffer), 00218 BLE_ERROR_PARAM_OUT_OF_RANGE ); 00219 } 00220 00221 return BLE_ERROR_NONE; 00222 } 00223 00224 /**************************************************************************/ 00225 /*! 00226 @brief Callback handler for events getting pushed up from the SD 00227 */ 00228 /**************************************************************************/ 00229 void nRF51GattServer::hwCallback(ble_evt_t *p_ble_evt) 00230 { 00231 uint16_t handle_value; 00232 GattServerEvents::gattEvent_t eventType; 00233 const ble_gatts_evt_t *gattsEventP = &p_ble_evt->evt.gatts_evt; 00234 00235 switch (p_ble_evt->header.evt_id) { 00236 case BLE_GATTS_EVT_WRITE: 00237 /* There are 2 use case here: Values being updated & CCCD (indicate/notify) enabled */ 00238 00239 /* 1.) Handle CCCD changes */ 00240 handle_value = gattsEventP->params.write.handle; 00241 for (uint8_t i = 0; i<characteristicCount; i++) { 00242 if ((p_characteristics[i]->getProperties() & (GattCharacteristic::BLE_GATT_CHAR_PROPERTIES_INDICATE | GattCharacteristic::BLE_GATT_CHAR_PROPERTIES_NOTIFY)) && 00243 (nrfCharacteristicHandles[i].cccd_handle == handle_value)) { 00244 uint16_t cccd_value = 00245 (gattsEventP->params.write.data[1] << 8) | 00246 gattsEventP->params.write.data[0]; /* Little Endian but M0 may be mis-aligned */ 00247 00248 if (((p_characteristics[i]->getProperties() & GattCharacteristic::BLE_GATT_CHAR_PROPERTIES_INDICATE) && (cccd_value & BLE_GATT_HVX_INDICATION)) || 00249 ((p_characteristics[i]->getProperties() & GattCharacteristic::BLE_GATT_CHAR_PROPERTIES_NOTIFY) && (cccd_value & BLE_GATT_HVX_NOTIFICATION))) { 00250 eventType = GattServerEvents::GATT_EVENT_UPDATES_ENABLED; 00251 } else { 00252 eventType = GattServerEvents::GATT_EVENT_UPDATES_DISABLED; 00253 } 00254 00255 handleEvent(eventType, i); 00256 return; 00257 } 00258 } 00259 00260 /* 2.) Changes to the characteristic value will be handled with other events below */ 00261 eventType = GattServerEvents::GATT_EVENT_DATA_WRITTEN; 00262 break; 00263 00264 case BLE_GATTS_EVT_HVC: 00265 /* Indication confirmation received */ 00266 eventType = GattServerEvents::GATT_EVENT_CONFIRMATION_RECEIVED; 00267 handle_value = gattsEventP->params.hvc.handle; 00268 break; 00269 00270 case BLE_EVT_TX_COMPLETE: { 00271 handleDataSentEvent(p_ble_evt->evt.common_evt.params.tx_complete.count); 00272 return; 00273 } 00274 00275 case BLE_GATTS_EVT_SYS_ATTR_MISSING: 00276 sd_ble_gatts_sys_attr_set(gattsEventP->conn_handle, NULL, 0); 00277 return; 00278 00279 case BLE_GATTS_EVT_RW_AUTHORIZE_REQUEST: 00280 switch (gattsEventP->params.authorize_request.type) { 00281 case BLE_GATTS_AUTHORIZE_TYPE_READ: 00282 eventType = GattServerEvents::GATT_EVENT_READ_AUTHORIZATION_REQ; 00283 handle_value = gattsEventP->params.authorize_request.request.read.handle; 00284 break; 00285 case BLE_GATTS_AUTHORIZE_TYPE_WRITE: 00286 eventType = GattServerEvents::GATT_EVENT_WRITE_AUTHORIZATION_REQ; 00287 handle_value = gattsEventP->params.authorize_request.request.write.handle; 00288 break; 00289 default: 00290 return; 00291 } 00292 break; 00293 00294 default: 00295 return; 00296 } 00297 00298 /* Find index (charHandle) in the pool */ 00299 for (uint8_t i = 0; i<characteristicCount; i++) { 00300 if (nrfCharacteristicHandles[i].value_handle == handle_value) { 00301 switch (eventType) { 00302 case GattServerEvents::GATT_EVENT_DATA_WRITTEN: { 00303 GattCharacteristicWriteCBParams cbParams = { 00304 .charHandle = i, 00305 .op = static_cast<GattCharacteristicWriteCBParams::Type>(gattsEventP->params.write.op), 00306 .offset = gattsEventP->params.write.offset, 00307 .len = gattsEventP->params.write.len, 00308 .data = gattsEventP->params.write.data 00309 }; 00310 handleDataWrittenEvent(&cbParams); 00311 break; 00312 } 00313 case GattServerEvents::GATT_EVENT_WRITE_AUTHORIZATION_REQ: { 00314 GattCharacteristicWriteAuthCBParams cbParams = { 00315 .charHandle = i, 00316 .offset = gattsEventP->params.authorize_request.request.write.offset, 00317 .len = gattsEventP->params.authorize_request.request.write.len, 00318 .data = gattsEventP->params.authorize_request.request.write.data, 00319 }; 00320 ble_gatts_rw_authorize_reply_params_t reply = { 00321 .type = BLE_GATTS_AUTHORIZE_TYPE_WRITE, 00322 .params = { 00323 .write = { 00324 .gatt_status = (p_characteristics[i]->authorizeWrite(&cbParams) ? 00325 BLE_GATT_STATUS_SUCCESS : BLE_GATT_STATUS_ATTERR_WRITE_NOT_PERMITTED) 00326 } 00327 } 00328 }; 00329 sd_ble_gatts_rw_authorize_reply(gattsEventP->conn_handle, &reply); 00330 break; 00331 } 00332 case GattServerEvents::GATT_EVENT_READ_AUTHORIZATION_REQ: { 00333 GattCharacteristicReadAuthCBParams cbParams = { 00334 .charHandle = i, 00335 .offset = gattsEventP->params.authorize_request.request.read.offset, 00336 }; 00337 ble_gatts_rw_authorize_reply_params_t reply = { 00338 .type = BLE_GATTS_AUTHORIZE_TYPE_READ, 00339 .params = { 00340 .read = { 00341 .gatt_status = (p_characteristics[i]->authorizeRead(&cbParams) ? 00342 BLE_GATT_STATUS_SUCCESS : BLE_GATT_STATUS_ATTERR_READ_NOT_PERMITTED) 00343 } 00344 } 00345 }; 00346 sd_ble_gatts_rw_authorize_reply(gattsEventP->conn_handle, &reply); 00347 break; 00348 } 00349 00350 default: 00351 handleEvent(eventType, i); 00352 break; 00353 } 00354 } 00355 } 00356 } 00357 00358 ble_error_t 00359 nRF51GattServer::initializeGATTDatabase(void) 00360 { 00361 /* Empty. Services are populated in the GattDatabase through addService(). */ 00362 return BLE_ERROR_NONE; 00363 }
Generated on Tue Jul 12 2022 15:04:24 by
1.7.2
