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