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 BLE_WallbotBLE_Challenge 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 &nrfCharacteristicHandles[characteristicCount]), 00080 BLE_ERROR_PARAM_OUT_OF_RANGE ); 00081 00082 /* Update the characteristic handle */ 00083 uint16_t charHandle = characteristicCount; 00084 p_characteristics[characteristicCount++] = p_char; 00085 00086 p_char->getValueAttribute().setHandle(charHandle); 00087 00088 /* Add optional descriptors if any */ 00089 /* ToDo: Make sure we don't overflow the array */ 00090 for (uint8_t j = 0; j < p_char->getDescriptorCount(); j++) { 00091 GattAttribute *p_desc = p_char->getDescriptor(j); 00092 00093 nordicUUID = custom_convert_to_nordic_uuid(p_desc->getUUID()); 00094 00095 ASSERT ( ERROR_NONE == 00096 custom_add_in_descriptor(BLE_GATT_HANDLE_INVALID, 00097 &nordicUUID, 00098 p_desc->getValuePtr(), 00099 p_desc->getInitialLength(), 00100 p_desc->getMaxLength(), 00101 &nrfDescriptorHandles[descriptorCount]), 00102 BLE_ERROR_PARAM_OUT_OF_RANGE ); 00103 00104 uint16_t descHandle = descriptorCount; 00105 p_descriptors[descriptorCount++] = p_desc; 00106 p_desc->setHandle(descHandle); 00107 } 00108 } 00109 00110 serviceCount++; 00111 00112 return BLE_ERROR_NONE; 00113 } 00114 00115 /**************************************************************************/ 00116 /*! 00117 @brief Reads the value of a characteristic, based on the service 00118 and characteristic index fields 00119 00120 @param[in] charHandle 00121 The handle of the GattCharacteristic to read from 00122 @param[in] buffer 00123 Buffer to hold the the characteristic's value 00124 (raw byte array in LSB format) 00125 @param[in] len 00126 The number of bytes read into the buffer 00127 00128 @returns ble_error_t 00129 00130 @retval BLE_ERROR_NONE 00131 Everything executed properly 00132 00133 @section EXAMPLE 00134 00135 @code 00136 00137 @endcode 00138 */ 00139 /**************************************************************************/ 00140 ble_error_t nRF51GattServer::readValue(uint16_t charHandle, uint8_t buffer[], uint16_t *const lengthP) 00141 { 00142 ASSERT( ERROR_NONE == 00143 sd_ble_gatts_value_get(nrfCharacteristicHandles[charHandle].value_handle, 0, lengthP, buffer), 00144 BLE_ERROR_PARAM_OUT_OF_RANGE); 00145 00146 return BLE_ERROR_NONE; 00147 } 00148 00149 /**************************************************************************/ 00150 /*! 00151 @brief Updates the value of a characteristic, based on the service 00152 and characteristic index fields 00153 00154 @param[in] charHandle 00155 The handle of the GattCharacteristic to write to 00156 @param[in] buffer 00157 Data to use when updating the characteristic's value 00158 (raw byte array in LSB format) 00159 @param[in] len 00160 The number of bytes in buffer 00161 00162 @returns ble_error_t 00163 00164 @retval BLE_ERROR_NONE 00165 Everything executed properly 00166 00167 @section EXAMPLE 00168 00169 @code 00170 00171 @endcode 00172 */ 00173 /**************************************************************************/ 00174 ble_error_t nRF51GattServer::updateValue(uint16_t charHandle, uint8_t buffer[], uint16_t len, bool localOnly) 00175 { 00176 uint16_t gapConnectionHandle = nRF51Gap::getInstance().getConnectionHandle(); 00177 00178 if (localOnly) { 00179 /* Only update locally regardless of notify/indicate */ 00180 ASSERT_INT( ERROR_NONE, 00181 sd_ble_gatts_value_set(nrfCharacteristicHandles[charHandle].value_handle, 0, &len, buffer), 00182 BLE_ERROR_PARAM_OUT_OF_RANGE ); 00183 return BLE_ERROR_NONE; 00184 } 00185 00186 if ((p_characteristics[charHandle]->getProperties() & 00187 (GattCharacteristic::BLE_GATT_CHAR_PROPERTIES_INDICATE | 00188 GattCharacteristic::BLE_GATT_CHAR_PROPERTIES_NOTIFY)) && 00189 (gapConnectionHandle != BLE_CONN_HANDLE_INVALID)) { 00190 /* HVX update for the characteristic value */ 00191 ble_gatts_hvx_params_t hvx_params; 00192 00193 hvx_params.handle = nrfCharacteristicHandles[charHandle].value_handle; 00194 hvx_params.type = 00195 (p_characteristics[charHandle]->getProperties() & 00196 GattCharacteristic::BLE_GATT_CHAR_PROPERTIES_NOTIFY) ? 00197 BLE_GATT_HVX_NOTIFICATION : BLE_GATT_HVX_INDICATION; 00198 hvx_params.offset = 0; 00199 hvx_params.p_data = buffer; 00200 hvx_params.p_len = &len; 00201 00202 error_t error = (error_t) sd_ble_gatts_hvx(gapConnectionHandle, &hvx_params); 00203 00204 /* ERROR_INVALID_STATE, ERROR_BUSY, ERROR_GATTS_SYS_ATTR_MISSING and 00205 *ERROR_NO_TX_BUFFERS the ATT table has been updated. */ 00206 if ((error != ERROR_NONE) && (error != ERROR_INVALID_STATE) && 00207 (error != ERROR_BLE_NO_TX_BUFFERS) && (error != ERROR_BUSY) && 00208 (error != ERROR_BLEGATTS_SYS_ATTR_MISSING)) { 00209 ASSERT_INT( ERROR_NONE, 00210 sd_ble_gatts_value_set(nrfCharacteristicHandles[charHandle].value_handle, 0, &len, buffer), 00211 BLE_ERROR_PARAM_OUT_OF_RANGE ); 00212 } 00213 } else { 00214 ASSERT_INT( ERROR_NONE, 00215 sd_ble_gatts_value_set(nrfCharacteristicHandles[charHandle].value_handle, 0, &len, buffer), 00216 BLE_ERROR_PARAM_OUT_OF_RANGE ); 00217 } 00218 00219 return BLE_ERROR_NONE; 00220 } 00221 00222 /**************************************************************************/ 00223 /*! 00224 @brief Callback handler for events getting pushed up from the SD 00225 */ 00226 /**************************************************************************/ 00227 void nRF51GattServer::hwCallback(ble_evt_t *p_ble_evt) 00228 { 00229 uint16_t handle_value; 00230 GattServerEvents::gattEvent_t eventType; 00231 const ble_gatts_evt_t *gattsEventP = &p_ble_evt->evt.gatts_evt; 00232 00233 switch (p_ble_evt->header.evt_id) { 00234 case BLE_GATTS_EVT_WRITE: 00235 /* There are 2 use case here: Values being updated & CCCD (indicate/notify) enabled */ 00236 00237 /* 1.) Handle CCCD changes */ 00238 handle_value = gattsEventP->params.write.handle; 00239 for (uint8_t i = 0; i<characteristicCount; i++) { 00240 if ((p_characteristics[i]->getProperties() & (GattCharacteristic::BLE_GATT_CHAR_PROPERTIES_INDICATE | GattCharacteristic::BLE_GATT_CHAR_PROPERTIES_NOTIFY)) && 00241 (nrfCharacteristicHandles[i].cccd_handle == handle_value)) { 00242 uint16_t cccd_value = 00243 (gattsEventP->params.write.data[1] << 8) | 00244 gattsEventP->params.write.data[0]; /* Little Endian but M0 may be mis-aligned */ 00245 00246 if (((p_characteristics[i]->getProperties() & GattCharacteristic::BLE_GATT_CHAR_PROPERTIES_INDICATE) && (cccd_value & BLE_GATT_HVX_INDICATION)) || 00247 ((p_characteristics[i]->getProperties() & GattCharacteristic::BLE_GATT_CHAR_PROPERTIES_NOTIFY) && (cccd_value & BLE_GATT_HVX_NOTIFICATION))) { 00248 eventType = GattServerEvents::GATT_EVENT_UPDATES_ENABLED; 00249 } else { 00250 eventType = GattServerEvents::GATT_EVENT_UPDATES_DISABLED; 00251 } 00252 00253 handleEvent(eventType, i); 00254 return; 00255 } 00256 } 00257 00258 /* 2.) Changes to the characteristic value will be handled with other events below */ 00259 eventType = GattServerEvents::GATT_EVENT_DATA_WRITTEN; 00260 break; 00261 00262 case BLE_GATTS_EVT_HVC: 00263 /* Indication confirmation received */ 00264 eventType = GattServerEvents::GATT_EVENT_CONFIRMATION_RECEIVED; 00265 handle_value = gattsEventP->params.hvc.handle; 00266 break; 00267 00268 case BLE_EVT_TX_COMPLETE: { 00269 handleDataSentEvent(p_ble_evt->evt.common_evt.params.tx_complete.count); 00270 return; 00271 } 00272 00273 case BLE_GATTS_EVT_SYS_ATTR_MISSING: 00274 sd_ble_gatts_sys_attr_set(gattsEventP->conn_handle, NULL, 0); 00275 return; 00276 00277 default: 00278 return; 00279 } 00280 00281 /* Find index (charHandle) in the pool */ 00282 for (uint8_t i = 0; i<characteristicCount; i++) { 00283 if (nrfCharacteristicHandles[i].value_handle == handle_value) { 00284 switch (eventType) { 00285 case GattServerEvents::GATT_EVENT_DATA_WRITTEN: { 00286 GattCharacteristicWriteCBParams cbParams = { 00287 .charHandle = i, 00288 .op = static_cast<GattCharacteristicWriteCBParams::Type>(gattsEventP->params.write.op), 00289 .offset = gattsEventP->params.write.offset, 00290 .len = gattsEventP->params.write.len, 00291 .data = gattsEventP->params.write.data 00292 }; 00293 handleDataWrittenEvent(&cbParams); 00294 break; 00295 } 00296 default: 00297 handleEvent(eventType, i); 00298 break; 00299 } 00300 } 00301 } 00302 }
Generated on Tue Jul 12 2022 13:52:31 by
