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.
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 /**************************************************************************/ 00024 /*! 00025 @brief Adds a new service to the GATT table on the peripheral 00026 00027 @returns ble_error_t 00028 00029 @retval BLE_ERROR_NONE 00030 Everything executed properly 00031 00032 @section EXAMPLE 00033 00034 @code 00035 00036 @endcode 00037 */ 00038 /**************************************************************************/ 00039 ble_error_t nRF51GattServer::addService(GattService & service) 00040 { 00041 /* ToDo: Make sure we don't overflow the array, etc. */ 00042 /* ToDo: Make sure this service UUID doesn't already exist (?) */ 00043 /* ToDo: Basic validation */ 00044 00045 /* Add the service to the nRF51 */ 00046 ble_uuid_t uuid; 00047 00048 if (service.primaryServiceID.type == UUID::UUID_TYPE_SHORT) 00049 { 00050 /* 16-bit BLE UUID */ 00051 uuid.type = BLE_UUID_TYPE_BLE; 00052 } 00053 else 00054 { 00055 /* 128-bit Custom UUID */ 00056 uuid.type = custom_add_uuid_base( service.primaryServiceID.base ); 00057 } 00058 00059 uuid.uuid = service.primaryServiceID.value; 00060 00061 ASSERT( ERROR_NONE == sd_ble_gatts_service_add(BLE_GATTS_SRVC_TYPE_PRIMARY, &uuid, &service.handle), BLE_ERROR_PARAM_OUT_OF_RANGE ); 00062 00063 /* Add characteristics to the service */ 00064 for (uint8_t i = 0; i < service.characteristicCount; i++) 00065 { 00066 GattCharacteristic * p_char = service.characteristics[i]; 00067 00068 uuid.uuid = p_char->uuid; 00069 ASSERT ( ERROR_NONE == custom_add_in_characteristic(service.handle, &uuid, p_char->properties, 00070 NULL, p_char->lenMin, p_char->lenMax, &nrfCharacteristicHandles[characteristicCount]), BLE_ERROR_PARAM_OUT_OF_RANGE ); 00071 00072 /* Update the characteristic handle */ 00073 p_char->handle = characteristicCount; 00074 p_characteristics[characteristicCount++] = p_char; 00075 } 00076 00077 serviceCount++; 00078 00079 return BLE_ERROR_NONE; 00080 } 00081 00082 /**************************************************************************/ 00083 /*! 00084 @brief Reads the value of a characteristic, based on the service 00085 and characteristic index fields 00086 00087 @param[in] charHandle 00088 The handle of the GattCharacteristic to read from 00089 @param[in] buffer 00090 Buffer to hold the the characteristic's value 00091 (raw byte array in LSB format) 00092 @param[in] len 00093 The number of bytes read into the buffer 00094 00095 @returns ble_error_t 00096 00097 @retval BLE_ERROR_NONE 00098 Everything executed properly 00099 00100 @section EXAMPLE 00101 00102 @code 00103 00104 @endcode 00105 */ 00106 /**************************************************************************/ 00107 ble_error_t nRF51GattServer::readValue(uint16_t charHandle, uint8_t buffer[], uint16_t len) 00108 { 00109 ASSERT( ERROR_NONE == sd_ble_gatts_value_get(nrfCharacteristicHandles[charHandle].value_handle, 0, &len, buffer), BLE_ERROR_PARAM_OUT_OF_RANGE); 00110 00111 return BLE_ERROR_NONE; 00112 } 00113 00114 /**************************************************************************/ 00115 /*! 00116 @brief Updates the value of a characteristic, based on the service 00117 and characteristic index fields 00118 00119 @param[in] charHandle 00120 The handle of the GattCharacteristic to write to 00121 @param[in] buffer 00122 Data to use when updating the characteristic's value 00123 (raw byte array in LSB format) 00124 @param[in] len 00125 The number of bytes in buffer 00126 00127 @returns ble_error_t 00128 00129 @retval BLE_ERROR_NONE 00130 Everything executed properly 00131 00132 @section EXAMPLE 00133 00134 @code 00135 00136 @endcode 00137 */ 00138 /**************************************************************************/ 00139 ble_error_t nRF51GattServer::updateValue(uint16_t charHandle, uint8_t buffer[], uint16_t len) 00140 { 00141 if ((p_characteristics[charHandle]->properties & (GattCharacteristic::BLE_GATT_CHAR_PROPERTIES_INDICATE | GattCharacteristic::BLE_GATT_CHAR_PROPERTIES_NOTIFY)) && 00142 (m_connectionHandle != BLE_CONN_HANDLE_INVALID) ) 00143 { 00144 /* HVX update for the characteristic value */ 00145 ble_gatts_hvx_params_t hvx_params; 00146 00147 hvx_params.handle = nrfCharacteristicHandles[charHandle].value_handle; 00148 hvx_params.type = (p_characteristics[charHandle]->properties & GattCharacteristic::BLE_GATT_CHAR_PROPERTIES_NOTIFY) ? BLE_GATT_HVX_NOTIFICATION : BLE_GATT_HVX_INDICATION; 00149 hvx_params.offset = 0; 00150 hvx_params.p_data = buffer; 00151 hvx_params.p_len = &len; 00152 00153 error_t error = (error_t) sd_ble_gatts_hvx(m_connectionHandle, &hvx_params); 00154 00155 /* ERROR_INVALID_STATE, ERROR_BUSY, ERROR_GATTS_SYS_ATTR_MISSING and ERROR_NO_TX_BUFFERS the ATT table has been updated. */ 00156 if ( (error != ERROR_NONE ) && (error != ERROR_INVALID_STATE) && 00157 (error != ERROR_BLE_NO_TX_BUFFERS ) && (error != ERROR_BUSY ) && 00158 (error != ERROR_BLEGATTS_SYS_ATTR_MISSING ) ) 00159 { 00160 ASSERT_INT( ERROR_NONE, sd_ble_gatts_value_set(nrfCharacteristicHandles[charHandle].value_handle, 0, &len, buffer), BLE_ERROR_PARAM_OUT_OF_RANGE ); 00161 } 00162 } else 00163 { 00164 ASSERT_INT( ERROR_NONE, sd_ble_gatts_value_set(nrfCharacteristicHandles[charHandle].value_handle, 0, &len, buffer), BLE_ERROR_PARAM_OUT_OF_RANGE ); 00165 } 00166 00167 return BLE_ERROR_NONE; 00168 } 00169 00170 /**************************************************************************/ 00171 /*! 00172 @brief Callback handler for events getting pushed up from the SD 00173 */ 00174 /**************************************************************************/ 00175 void nRF51GattServer::hwCallback(ble_evt_t * p_ble_evt) 00176 { 00177 uint16_t handle_value; 00178 GattServerEvents::gattEvent_t event; 00179 00180 switch (p_ble_evt->header.evt_id) 00181 { 00182 case BLE_GATTS_EVT_WRITE: 00183 /* There are 2 use case here: Values being updated & CCCD (indicate/notify) enabled */ 00184 00185 /* 1.) Handle CCCD changes */ 00186 handle_value = p_ble_evt->evt.gatts_evt.params.write.handle; 00187 for(uint8_t i=0; i<characteristicCount; i++) 00188 { 00189 if ( (p_characteristics[i]->properties & (GattCharacteristic::BLE_GATT_CHAR_PROPERTIES_INDICATE | GattCharacteristic::BLE_GATT_CHAR_PROPERTIES_NOTIFY)) && 00190 (nrfCharacteristicHandles[i].cccd_handle == handle_value) ) 00191 { 00192 uint16_t cccd_value = (p_ble_evt->evt.gatts_evt.params.write.data[1] << 8) | p_ble_evt->evt.gatts_evt.params.write.data[0]; /* Little Endian but M0 may be mis-aligned */ 00193 00194 if ( ((p_characteristics[i]->properties & GattCharacteristic::BLE_GATT_CHAR_PROPERTIES_INDICATE) && (cccd_value & BLE_GATT_HVX_INDICATION )) || 00195 ((p_characteristics[i]->properties & GattCharacteristic::BLE_GATT_CHAR_PROPERTIES_NOTIFY ) && (cccd_value & BLE_GATT_HVX_NOTIFICATION))) 00196 { 00197 event = GattServerEvents::GATT_EVENT_UPDATES_ENABLED; 00198 } else 00199 { 00200 event = GattServerEvents::GATT_EVENT_UPDATES_DISABLED; 00201 } 00202 00203 handleEvent(event, i); 00204 return; 00205 } 00206 } 00207 00208 /* 2.) Changes to the characteristic value will be handled with other events below */ 00209 event = GattServerEvents::GATT_EVENT_DATA_WRITTEN; 00210 break; 00211 00212 case BLE_GATTS_EVT_HVC: 00213 /* Indication confirmation received */ 00214 event = GattServerEvents::GATT_EVENT_CONFIRMATION_RECEIVED; 00215 handle_value = p_ble_evt->evt.gatts_evt.params.hvc.handle; 00216 break; 00217 00218 default: 00219 return; 00220 } 00221 00222 /* Find index (charHandle) in the pool */ 00223 for(uint8_t i=0; i<characteristicCount; i++) 00224 { 00225 if (nrfCharacteristicHandles[i].value_handle == handle_value) 00226 { 00227 handleEvent(event, i); 00228 break; 00229 } 00230 } 00231 }
Generated on Tue Jul 12 2022 12:14:19 by
