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