Nordic stack and drivers for the mbed BLE API Modified for HRM1017 for library 0.1.0
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 1.7.2