SG RFID nRF51822 fork
Fork of nRF51822 by
Embed:
(wiki syntax)
Show/hide line numbers
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 p_char->isReadAuthorizationEnabled(), 00080 p_char->isWriteAuthorizationEnabled(), 00081 &nrfCharacteristicHandles[characteristicCount]), 00082 BLE_ERROR_PARAM_OUT_OF_RANGE ); 00083 00084 /* Update the characteristic handle */ 00085 uint16_t charHandle = characteristicCount; 00086 p_characteristics[characteristicCount++] = p_char; 00087 00088 p_char->getValueAttribute().setHandle(charHandle); 00089 00090 /* Add optional descriptors if any */ 00091 /* ToDo: Make sure we don't overflow the array */ 00092 for (uint8_t j = 0; j < p_char->getDescriptorCount(); j++) { 00093 GattAttribute *p_desc = p_char->getDescriptor(j); 00094 00095 nordicUUID = custom_convert_to_nordic_uuid(p_desc->getUUID()); 00096 00097 ASSERT ( ERROR_NONE == 00098 custom_add_in_descriptor(BLE_GATT_HANDLE_INVALID, 00099 &nordicUUID, 00100 p_desc->getValuePtr(), 00101 p_desc->getInitialLength(), 00102 p_desc->getMaxLength(), 00103 &nrfDescriptorHandles[descriptorCount]), 00104 BLE_ERROR_PARAM_OUT_OF_RANGE ); 00105 00106 uint16_t descHandle = descriptorCount; 00107 p_descriptors[descriptorCount++] = p_desc; 00108 p_desc->setHandle(descHandle); 00109 } 00110 } 00111 00112 serviceCount++; 00113 00114 return BLE_ERROR_NONE; 00115 } 00116 00117 /**************************************************************************/ 00118 /*! 00119 @brief Reads the value of a characteristic, based on the service 00120 and characteristic index fields 00121 00122 @param[in] charHandle 00123 The handle of the GattCharacteristic to read from 00124 @param[in] buffer 00125 Buffer to hold the the characteristic's value 00126 (raw byte array in LSB format) 00127 @param[in] len 00128 The number of bytes read into the buffer 00129 00130 @returns ble_error_t 00131 00132 @retval BLE_ERROR_NONE 00133 Everything executed properly 00134 00135 @section EXAMPLE 00136 00137 @code 00138 00139 @endcode 00140 */ 00141 /**************************************************************************/ 00142 ble_error_t nRF51GattServer::readValue(GattAttribute::Handle_t charHandle, uint8_t buffer[], uint16_t *const lengthP) 00143 { 00144 ASSERT( ERROR_NONE == 00145 sd_ble_gatts_value_get(nrfCharacteristicHandles[charHandle].value_handle, 0, lengthP, buffer), 00146 BLE_ERROR_PARAM_OUT_OF_RANGE); 00147 00148 return BLE_ERROR_NONE; 00149 } 00150 00151 /**************************************************************************/ 00152 /*! 00153 @brief Updates the value of a characteristic, based on the service 00154 and characteristic index fields 00155 00156 @param[in] charHandle 00157 The handle of the GattCharacteristic to write to 00158 @param[in] buffer 00159 Data to use when updating the characteristic's value 00160 (raw byte array in LSB format) 00161 @param[in] len 00162 The number of bytes in buffer 00163 00164 @returns ble_error_t 00165 00166 @retval BLE_ERROR_NONE 00167 Everything executed properly 00168 00169 @section EXAMPLE 00170 00171 @code 00172 00173 @endcode 00174 */ 00175 /**************************************************************************/ 00176 ble_error_t nRF51GattServer::updateValue(GattAttribute::Handle_t charHandle, uint8_t buffer[], uint16_t len, bool localOnly) 00177 { 00178 uint16_t gapConnectionHandle = nRF51Gap::getInstance().getConnectionHandle(); 00179 ble_error_t returnValue = BLE_ERROR_NONE; 00180 00181 if (localOnly) { 00182 /* Only update locally regardless of notify/indicate */ 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 return BLE_ERROR_NONE; 00187 } 00188 00189 if ((p_characteristics[charHandle]->getProperties() & 00190 (GattCharacteristic::BLE_GATT_CHAR_PROPERTIES_INDICATE | 00191 GattCharacteristic::BLE_GATT_CHAR_PROPERTIES_NOTIFY)) && 00192 (gapConnectionHandle != BLE_CONN_HANDLE_INVALID)) { 00193 /* HVX update for the characteristic value */ 00194 ble_gatts_hvx_params_t hvx_params; 00195 00196 hvx_params.handle = nrfCharacteristicHandles[charHandle].value_handle; 00197 hvx_params.type = 00198 (p_characteristics[charHandle]->getProperties() & 00199 GattCharacteristic::BLE_GATT_CHAR_PROPERTIES_NOTIFY) ? 00200 BLE_GATT_HVX_NOTIFICATION : BLE_GATT_HVX_INDICATION; 00201 hvx_params.offset = 0; 00202 hvx_params.p_data = buffer; 00203 hvx_params.p_len = &len; 00204 00205 error_t error = (error_t) sd_ble_gatts_hvx(gapConnectionHandle, &hvx_params); 00206 00207 /* ERROR_INVALID_STATE, ERROR_BUSY, ERROR_GATTS_SYS_ATTR_MISSING and 00208 *ERROR_NO_TX_BUFFERS the ATT table has been updated. */ 00209 if ((error != ERROR_NONE) && (error != ERROR_INVALID_STATE) && 00210 (error != ERROR_BLE_NO_TX_BUFFERS) && (error != ERROR_BUSY) && 00211 (error != ERROR_BLEGATTS_SYS_ATTR_MISSING)) { 00212 ASSERT_INT( ERROR_NONE, 00213 sd_ble_gatts_value_set(nrfCharacteristicHandles[charHandle].value_handle, 0, &len, buffer), 00214 BLE_ERROR_PARAM_OUT_OF_RANGE ); 00215 } 00216 00217 /* Notifications consume application buffers. The return value can 00218 be used for resending notifications. 00219 */ 00220 if (error != ERROR_NONE) { 00221 returnValue = BLE_STACK_BUSY; 00222 } 00223 } else { 00224 ASSERT_INT( ERROR_NONE, 00225 sd_ble_gatts_value_set(nrfCharacteristicHandles[charHandle].value_handle, 0, &len, buffer), 00226 BLE_ERROR_PARAM_OUT_OF_RANGE ); 00227 } 00228 00229 return returnValue; 00230 } 00231 00232 /**************************************************************************/ 00233 /*! 00234 @brief Callback handler for events getting pushed up from the SD 00235 */ 00236 /**************************************************************************/ 00237 void nRF51GattServer::hwCallback(ble_evt_t *p_ble_evt) 00238 { 00239 uint16_t handle_value; 00240 GattServerEvents::gattEvent_t eventType; 00241 const ble_gatts_evt_t *gattsEventP = &p_ble_evt->evt.gatts_evt; 00242 00243 switch (p_ble_evt->header.evt_id) { 00244 case BLE_GATTS_EVT_WRITE: 00245 /* There are 2 use case here: Values being updated & CCCD (indicate/notify) enabled */ 00246 00247 /* 1.) Handle CCCD changes */ 00248 handle_value = gattsEventP->params.write.handle; 00249 for (uint8_t i = 0; i<characteristicCount; i++) { 00250 if ((p_characteristics[i]->getProperties() & (GattCharacteristic::BLE_GATT_CHAR_PROPERTIES_INDICATE | GattCharacteristic::BLE_GATT_CHAR_PROPERTIES_NOTIFY)) && 00251 (nrfCharacteristicHandles[i].cccd_handle == handle_value)) { 00252 uint16_t cccd_value = 00253 (gattsEventP->params.write.data[1] << 8) | 00254 gattsEventP->params.write.data[0]; /* Little Endian but M0 may be mis-aligned */ 00255 00256 if (((p_characteristics[i]->getProperties() & GattCharacteristic::BLE_GATT_CHAR_PROPERTIES_INDICATE) && (cccd_value & BLE_GATT_HVX_INDICATION)) || 00257 ((p_characteristics[i]->getProperties() & GattCharacteristic::BLE_GATT_CHAR_PROPERTIES_NOTIFY) && (cccd_value & BLE_GATT_HVX_NOTIFICATION))) { 00258 eventType = GattServerEvents::GATT_EVENT_UPDATES_ENABLED; 00259 } else { 00260 eventType = GattServerEvents::GATT_EVENT_UPDATES_DISABLED; 00261 } 00262 00263 handleEvent(eventType, i); 00264 return; 00265 } 00266 } 00267 00268 /* 2.) Changes to the characteristic value will be handled with other events below */ 00269 eventType = GattServerEvents::GATT_EVENT_DATA_WRITTEN; 00270 break; 00271 00272 case BLE_GATTS_EVT_HVC: 00273 /* Indication confirmation received */ 00274 eventType = GattServerEvents::GATT_EVENT_CONFIRMATION_RECEIVED; 00275 handle_value = gattsEventP->params.hvc.handle; 00276 break; 00277 00278 case BLE_EVT_TX_COMPLETE: { 00279 handleDataSentEvent(p_ble_evt->evt.common_evt.params.tx_complete.count); 00280 return; 00281 } 00282 00283 case BLE_GATTS_EVT_SYS_ATTR_MISSING: 00284 sd_ble_gatts_sys_attr_set(gattsEventP->conn_handle, NULL, 0); 00285 return; 00286 00287 case BLE_GATTS_EVT_RW_AUTHORIZE_REQUEST: 00288 switch (gattsEventP->params.authorize_request.type) { 00289 case BLE_GATTS_AUTHORIZE_TYPE_READ: 00290 eventType = GattServerEvents::GATT_EVENT_READ_AUTHORIZATION_REQ; 00291 handle_value = gattsEventP->params.authorize_request.request.read.handle; 00292 break; 00293 case BLE_GATTS_AUTHORIZE_TYPE_WRITE: 00294 eventType = GattServerEvents::GATT_EVENT_WRITE_AUTHORIZATION_REQ; 00295 handle_value = gattsEventP->params.authorize_request.request.write.handle; 00296 break; 00297 default: 00298 return; 00299 } 00300 break; 00301 00302 default: 00303 return; 00304 } 00305 00306 /* Find index (charHandle) in the pool */ 00307 for (uint8_t i = 0; i < characteristicCount; i++) { 00308 if (nrfCharacteristicHandles[i].value_handle == handle_value) { 00309 switch (eventType) { 00310 case GattServerEvents::GATT_EVENT_DATA_WRITTEN: { 00311 GattCharacteristicWriteCBParams cbParams = { 00312 .charHandle = i, 00313 .op = static_cast<GattCharacteristicWriteCBParams::Type>(gattsEventP->params.write.op), 00314 .offset = gattsEventP->params.write.offset, 00315 .len = gattsEventP->params.write.len, 00316 .data = gattsEventP->params.write.data 00317 }; 00318 handleDataWrittenEvent(&cbParams); 00319 break; 00320 } 00321 case GattServerEvents::GATT_EVENT_WRITE_AUTHORIZATION_REQ: { 00322 GattCharacteristicWriteAuthCBParams cbParams = { 00323 .charHandle = i, 00324 .offset = gattsEventP->params.authorize_request.request.write.offset, 00325 .len = gattsEventP->params.authorize_request.request.write.len, 00326 .data = gattsEventP->params.authorize_request.request.write.data, 00327 }; 00328 ble_gatts_rw_authorize_reply_params_t reply = { 00329 .type = BLE_GATTS_AUTHORIZE_TYPE_WRITE, 00330 .params = { 00331 .write = { 00332 .gatt_status = (p_characteristics[i]->authorizeWrite(&cbParams) ? 00333 BLE_GATT_STATUS_SUCCESS : BLE_GATT_STATUS_ATTERR_WRITE_NOT_PERMITTED) 00334 } 00335 } 00336 }; 00337 sd_ble_gatts_rw_authorize_reply(gattsEventP->conn_handle, &reply); 00338 00339 /* 00340 * If write-authorization is enabled for a characteristic, 00341 * AUTHORIZATION_REQ event (if replied with true) is *not* 00342 * followed by another DATA_WRITTEN event; so we still need 00343 * to invoke handleDataWritten(), much the same as we would 00344 * have done if write-authorization had not been enabled. 00345 */ 00346 if (reply.params.write.gatt_status == BLE_GATT_STATUS_SUCCESS) { 00347 GattCharacteristicWriteCBParams cbParams = { 00348 .charHandle = i, 00349 .op = static_cast<GattCharacteristicWriteCBParams::Type>(gattsEventP->params.authorize_request.request.write.op), 00350 .offset = gattsEventP->params.authorize_request.request.write.offset, 00351 .len = gattsEventP->params.authorize_request.request.write.len, 00352 .data = gattsEventP->params.authorize_request.request.write.data, 00353 }; 00354 handleDataWrittenEvent(&cbParams); 00355 } 00356 break; 00357 } 00358 case GattServerEvents::GATT_EVENT_READ_AUTHORIZATION_REQ: { 00359 GattCharacteristicReadAuthCBParams cbParams = { 00360 .charHandle = i, 00361 .offset = gattsEventP->params.authorize_request.request.read.offset, 00362 .len = 0, 00363 .data = NULL 00364 }; 00365 00366 /* Ask for authorization and, potentially, new data. Use updated parameters to construct reply. */ 00367 p_characteristics[i]->authorizeRead(&cbParams); 00368 00369 ble_gatts_rw_authorize_reply_params_t reply = { 00370 .type = BLE_GATTS_AUTHORIZE_TYPE_READ 00371 }; 00372 00373 if (cbParams.authorizationReply == true) { 00374 reply.params.read.gatt_status = BLE_GATT_STATUS_SUCCESS; 00375 00376 if (cbParams.data != NULL) { 00377 reply.params.read.update = 1; 00378 reply.params.read.offset = cbParams.offset; 00379 reply.params.read.len = cbParams.len; 00380 reply.params.read.p_data = cbParams.data; 00381 } 00382 } else { 00383 reply.params.read.gatt_status = BLE_GATT_STATUS_ATTERR_READ_NOT_PERMITTED; 00384 } 00385 00386 sd_ble_gatts_rw_authorize_reply(gattsEventP->conn_handle, &reply); 00387 break; 00388 } 00389 00390 default: 00391 handleEvent(eventType, i); 00392 break; 00393 } 00394 } 00395 } 00396 } 00397 00398 ble_error_t 00399 nRF51GattServer::initializeGATTDatabase(void) 00400 { 00401 /* Empty. Services are populated in the GattDatabase through addService(). */ 00402 return BLE_ERROR_NONE; 00403 }
Generated on Tue Jul 12 2022 15:07:44 by 1.7.2