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->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 } 00159 00160 if ((p_characteristics[charHandle]->getProperties() & 00161 (GattCharacteristic::BLE_GATT_CHAR_PROPERTIES_INDICATE | 00162 GattCharacteristic::BLE_GATT_CHAR_PROPERTIES_NOTIFY)) && 00163 (gapConnectionHandle != BLE_CONN_HANDLE_INVALID)) { 00164 /* HVX update for the characteristic value */ 00165 ble_gatts_hvx_params_t hvx_params; 00166 00167 hvx_params.handle = nrfCharacteristicHandles[charHandle].value_handle; 00168 hvx_params.type = 00169 (p_characteristics[charHandle]->getProperties() & 00170 GattCharacteristic::BLE_GATT_CHAR_PROPERTIES_NOTIFY) ? 00171 BLE_GATT_HVX_NOTIFICATION : BLE_GATT_HVX_INDICATION; 00172 hvx_params.offset = 0; 00173 hvx_params.p_data = buffer; 00174 hvx_params.p_len = &len; 00175 00176 error_t error = (error_t) sd_ble_gatts_hvx(gapConnectionHandle, &hvx_params); 00177 00178 /* ERROR_INVALID_STATE, ERROR_BUSY, ERROR_GATTS_SYS_ATTR_MISSING and 00179 *ERROR_NO_TX_BUFFERS the ATT table has been updated. */ 00180 if ((error != ERROR_NONE) && (error != ERROR_INVALID_STATE) && 00181 (error != ERROR_BLE_NO_TX_BUFFERS) && (error != ERROR_BUSY) && 00182 (error != ERROR_BLEGATTS_SYS_ATTR_MISSING)) { 00183 ASSERT_INT( ERROR_NONE, 00184 sd_ble_gatts_value_set(nrfCharacteristicHandles[charHandle].value_handle, 0, &len, buffer), 00185 BLE_ERROR_PARAM_OUT_OF_RANGE ); 00186 } 00187 } else { 00188 ASSERT_INT( ERROR_NONE, 00189 sd_ble_gatts_value_set(nrfCharacteristicHandles[charHandle].value_handle, 0, &len, buffer), 00190 BLE_ERROR_PARAM_OUT_OF_RANGE ); 00191 } 00192 00193 return BLE_ERROR_NONE; 00194 } 00195 00196 /**************************************************************************/ 00197 /*! 00198 @brief Callback handler for events getting pushed up from the SD 00199 */ 00200 /**************************************************************************/ 00201 void nRF51GattServer::hwCallback(ble_evt_t *p_ble_evt) 00202 { 00203 uint16_t handle_value; 00204 GattServerEvents::gattEvent_t event; 00205 00206 switch (p_ble_evt->header.evt_id) { 00207 case BLE_GATTS_EVT_WRITE: 00208 /* There are 2 use case here: Values being updated & CCCD (indicate/notify) enabled */ 00209 00210 /* 1.) Handle CCCD changes */ 00211 handle_value = p_ble_evt->evt.gatts_evt.params.write.handle; 00212 for (uint8_t i = 0; i<characteristicCount; i++) { 00213 if ((p_characteristics[i]->getProperties() & 00214 (GattCharacteristic::BLE_GATT_CHAR_PROPERTIES_INDICATE | 00215 GattCharacteristic::BLE_GATT_CHAR_PROPERTIES_NOTIFY)) && 00216 (nrfCharacteristicHandles[i].cccd_handle == handle_value)) { 00217 uint16_t cccd_value = 00218 (p_ble_evt->evt.gatts_evt.params.write.data[1] << 8) | 00219 p_ble_evt->evt.gatts_evt.params.write.data[0]; /* Little Endian but M0 may be mis-aligned */ 00220 00221 if (((p_characteristics[i]->getProperties() & 00222 GattCharacteristic::BLE_GATT_CHAR_PROPERTIES_INDICATE) && 00223 (cccd_value & BLE_GATT_HVX_INDICATION)) || 00224 ((p_characteristics[i]->getProperties() & 00225 GattCharacteristic::BLE_GATT_CHAR_PROPERTIES_NOTIFY) && 00226 (cccd_value & BLE_GATT_HVX_NOTIFICATION))) { 00227 event = GattServerEvents::GATT_EVENT_UPDATES_ENABLED; 00228 } else { 00229 event = GattServerEvents::GATT_EVENT_UPDATES_DISABLED; 00230 } 00231 00232 handleEvent(event, i); 00233 return; 00234 } 00235 } 00236 00237 /* 2.) Changes to the characteristic value will be handled with other 00238 * events below */ 00239 event = GattServerEvents::GATT_EVENT_DATA_WRITTEN; 00240 break; 00241 00242 case BLE_GATTS_EVT_HVC: 00243 /* Indication confirmation received */ 00244 event = GattServerEvents::GATT_EVENT_CONFIRMATION_RECEIVED; 00245 handle_value = p_ble_evt->evt.gatts_evt.params.hvc.handle; 00246 break; 00247 00248 default: 00249 return; 00250 } 00251 00252 /* Find index (charHandle) in the pool */ 00253 for (uint8_t i = 0; i<characteristicCount; i++) { 00254 if (nrfCharacteristicHandles[i].value_handle == handle_value) { 00255 handleEvent(event, i); 00256 break; 00257 } 00258 } 00259 }
Generated on Tue Jul 12 2022 19:00:52 by
