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.
Dependents: BLE_HeartRate_IDB0XA1
Fork of X_NUCLEO_IDB0XA1 by
BlueNRGGattServer.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 ****************************************************************************** 00018 * @file BlueNRGGattServer.cpp 00019 * @author STMicroelectronics 00020 * @brief Implementation of BlueNRG BLE_API GattServer Class 00021 ****************************************************************************** 00022 * @copy 00023 * 00024 * THE PRESENT FIRMWARE WHICH IS FOR GUIDANCE ONLY AIMS AT PROVIDING CUSTOMERS 00025 * WITH CODING INFORMATION REGARDING THEIR PRODUCTS IN ORDER FOR THEM TO SAVE 00026 * TIME. AS A RESULT, STMICROELECTRONICS SHALL NOT BE HELD LIABLE FOR ANY 00027 * DIRECT, INDIRECT OR CONSEQUENTIAL DAMAGES WITH RESPECT TO ANY CLAIMS ARISING 00028 * FROM THE CONTENT OF SUCH FIRMWARE AND/OR THE USE MADE BY CUSTOMERS OF THE 00029 * CODING INFORMATION CONTAINED HEREIN IN CONNECTION WITH THEIR PRODUCTS. 00030 * 00031 * <h2><center>© COPYRIGHT 2013 STMicroelectronics</center></h2> 00032 */ 00033 00034 /** @defgroup BlueNRGGATTSERVER 00035 * @brief BlueNRG BLE_API GattServer Adaptation 00036 * @{ 00037 */ 00038 00039 #include "BlueNRGGattServer.h" 00040 #include "mbed.h" 00041 #include "BlueNRGGap.h" 00042 #include "Utils.h" 00043 #include "debug.h" 00044 00045 /**************************************************************************/ 00046 /*! 00047 @brief Adds a new service to the GATT table on the peripheral 00048 00049 @params[in] service 00050 Pointer to instance of the Gatt Server to add 00051 00052 @returns ble_error_t 00053 00054 @retval BLE_ERROR_NONE 00055 Everything executed properly 00056 00057 @section EXAMPLE 00058 00059 @code 00060 00061 @endcode 00062 */ 00063 /**************************************************************************/ 00064 ble_error_t BlueNRGGattServer::addService(GattService &service) 00065 { 00066 /* ToDo: Make sure we don't overflow the array, etc. */ 00067 /* ToDo: Make sure this service UUID doesn't already exist (?) */ 00068 /* ToDo: Basic validation */ 00069 00070 tBleStatus ret; 00071 uint8_t type; 00072 uint16_t short_uuid; 00073 uint8_t primary_short_uuid[2]; 00074 uint8_t primary_base_uuid[16]; 00075 uint8_t char_base_uuid[16]; 00076 const uint8_t *base_uuid; 00077 const uint8_t *base_char_uuid; 00078 00079 uint8_t charsCount = 0; 00080 uint8_t maxAttrRecords = 0; 00081 00082 type = (service.getUUID()).shortOrLong(); 00083 PRINTF("AddService(): Type:%d\n\r", type); 00084 00085 /* Add the service to the BlueNRG */ 00086 short_uuid = (service.getUUID()).getShortUUID(); 00087 STORE_LE_16(primary_short_uuid, short_uuid); 00088 00089 if(type==UUID::UUID_TYPE_LONG) { 00090 base_uuid = (service.getUUID()).getBaseUUID(); 00091 00092 COPY_UUID_128(primary_base_uuid, base_uuid[15],base_uuid[14],primary_short_uuid[1],primary_short_uuid[0],base_uuid[11],base_uuid[10],base_uuid[9],base_uuid[8],base_uuid[7],base_uuid[6],base_uuid[5],base_uuid[4],base_uuid[3],base_uuid[2],base_uuid[1],base_uuid[0]); 00093 } 00094 00095 charsCount = service.getCharacteristicCount(); 00096 //1(service record)+2records*char+1record*char_desc 00097 maxAttrRecords = 1+3*charsCount; 00098 00099 if(type==UUID::UUID_TYPE_SHORT) { 00100 ret = aci_gatt_add_serv(UUID_TYPE_16, 00101 primary_short_uuid, 00102 PRIMARY_SERVICE, 00103 maxAttrRecords/*7*/, 00104 &servHandle); 00105 PRINTF("aci_gatt_add_serv UUID_TYPE_LONG ret=%d\n\r", ret); 00106 } 00107 else if(type==UUID::UUID_TYPE_LONG) { 00108 ret = aci_gatt_add_serv(UUID_TYPE_128, 00109 primary_base_uuid, 00110 PRIMARY_SERVICE, 00111 maxAttrRecords/*7*/, 00112 &servHandle); 00113 PRINTF("aci_gatt_add_serv UUID_TYPE_LONG ret=%d\n\r", ret); 00114 } 00115 00116 service.setHandle(servHandle); 00117 //serviceHandleVector.push_back(servHandle); 00118 PRINTF("added servHandle handle =%u\n\r", servHandle); 00119 uint16_t bleCharacteristic; 00120 00121 //iterate to include all characteristics 00122 for (uint8_t i = 0; i < charsCount; i++) { 00123 GattCharacteristic *p_char = service.getCharacteristic(i); 00124 uint16_t char_uuid = (p_char->getValueAttribute().getUUID()).getShortUUID(); 00125 00126 uint8_t int_8_uuid[2]; 00127 STORE_LE_16(int_8_uuid, char_uuid); 00128 00129 type = (p_char->getValueAttribute().getUUID()).shortOrLong(); 00130 00131 if(type==UUID::UUID_TYPE_LONG) { 00132 base_char_uuid = (p_char->getValueAttribute().getUUID()).getBaseUUID(); 00133 #ifdef DEBUG 00134 for(uint8_t j=0; j<16; j++) { 00135 PRINTF("base_char_uuid[%d] 0x%02x ", j, base_char_uuid[j]); 00136 } 00137 PRINTF("\n\r"); 00138 #endif 00139 COPY_UUID_128(char_base_uuid,base_char_uuid[15],base_char_uuid[14],int_8_uuid[1],int_8_uuid[0],base_char_uuid[11],base_char_uuid[10],base_char_uuid[9],base_char_uuid[8],base_char_uuid[7],base_char_uuid[6],base_char_uuid[5],base_char_uuid[4],base_char_uuid[3],base_char_uuid[2],base_char_uuid[1],base_char_uuid[0]); 00140 } 00141 00142 PRINTF("Char Properties 0x%x\n\r", p_char->getProperties()); 00143 /* 00144 * Gatt_Evt_Mask -> HardCoded (0) 00145 * Encryption_Key_Size -> Hardcoded (16) 00146 * isVariable (variable length value field) -> Hardcoded (1) 00147 */ 00148 uint8_t Gatt_Evt_Mask = 0x0; 00149 00150 if((p_char->getProperties() & 00151 (GattCharacteristic::BLE_GATT_CHAR_PROPERTIES_WRITE_WITHOUT_RESPONSE| 00152 GattCharacteristic::BLE_GATT_CHAR_PROPERTIES_WRITE))) { 00153 PRINTF("Setting up Gatt GATT_NOTIFY_ATTRIBUTE_WRITE Mask\n\r"); 00154 Gatt_Evt_Mask = Gatt_Evt_Mask | GATT_NOTIFY_ATTRIBUTE_WRITE; 00155 } 00156 if((p_char->getProperties() & 00157 (GattCharacteristic::BLE_GATT_CHAR_PROPERTIES_READ| 00158 GattCharacteristic::BLE_GATT_CHAR_PROPERTIES_NOTIFY| GattCharacteristic::BLE_GATT_CHAR_PROPERTIES_INDICATE))) { 00159 PRINTF("Setting up Gatt GATT_NOTIFY_READ_REQ_AND_WAIT_FOR_APPL_RESP Mask\n\r"); 00160 Gatt_Evt_Mask = Gatt_Evt_Mask | GATT_NOTIFY_READ_REQ_AND_WAIT_FOR_APPL_RESP; 00161 } //This will support also GATT_SERVER_ATTR_READ_WRITE since it will be covered by previous if() check. 00162 00163 if(type==UUID::UUID_TYPE_SHORT) { 00164 ret = aci_gatt_add_char(service.getHandle(), 00165 UUID_TYPE_16, 00166 int_8_uuid, 00167 p_char->getValueAttribute().getMaxLength() /*2*/ /*Value Length*/, 00168 p_char->getProperties(), 00169 ATTR_PERMISSION_NONE, 00170 Gatt_Evt_Mask /*Gatt_Evt_Mask*/, 00171 16 /*Encryption_Key_Size*/, 00172 1 /*isVariable*/, 00173 &bleCharacteristic); 00174 00175 PRINTF("aci_gatt_add_char UUID_TYPE_16 props=%d MaxLength=%d ret=%d\n\r", 00176 p_char->getProperties(), p_char->getValueAttribute().getMaxLength(), ret); 00177 00178 } else if(type==UUID::UUID_TYPE_LONG) { 00179 ret = aci_gatt_add_char(service.getHandle(), 00180 UUID_TYPE_128, 00181 char_base_uuid, 00182 p_char->getValueAttribute().getMaxLength() /*2*/ /*Value Length*/, 00183 p_char->getProperties(), 00184 ATTR_PERMISSION_NONE, 00185 Gatt_Evt_Mask /*Gatt_Evt_Mask*/, 00186 16 /*Encryption_Key_Size*/, 00187 1 /*isVariable*/, 00188 &bleCharacteristic); 00189 00190 PRINTF("aci_gatt_add_char UUID_TYPE_128 props=%d MaxLength=%d ret=%d\n\r", 00191 p_char->getProperties(), p_char->getValueAttribute().getMaxLength(), ret); 00192 } 00193 00194 bleCharHandleMap.insert(std::pair<uint16_t, uint16_t>(bleCharacteristic, servHandle)); 00195 00196 p_characteristics[characteristicCount++] = p_char; 00197 /* Set the characteristic value handle */ 00198 p_char->getValueAttribute().setHandle(bleCharacteristic+BlueNRGGattServer::CHAR_VALUE_HANDLE); 00199 PRINTF("added bleCharacteristic (value handle =%u)\n\r", p_char->getValueAttribute().getHandle()); 00200 00201 if ((p_char->getValueAttribute().getValuePtr() != NULL) && (p_char->getValueAttribute().getLength() > 0)) { 00202 write(p_char->getValueAttribute().getHandle(), 00203 p_char->getValueAttribute().getValuePtr(), 00204 p_char->getValueAttribute().getLength(), false /* localOnly */); 00205 } 00206 00207 // add descriptors now 00208 uint16_t descHandle = 0; 00209 PRINTF("p_char->getDescriptorCount()=%d\n\r", p_char->getDescriptorCount()); 00210 00211 for(uint8_t descIndex=0; descIndex<p_char->getDescriptorCount(); descIndex++) { 00212 GattAttribute *descriptor = p_char->getDescriptor(descIndex); 00213 uint16_t shortUUID = descriptor->getUUID().getShortUUID(); 00214 const uint8_t uuidArray[] = {(uint8_t)((shortUUID>>8)&0xFF), (uint8_t)((shortUUID&0xFF))}; 00215 ret = aci_gatt_add_char_desc(service.getHandle(), 00216 bleCharacteristic, 00217 CHAR_DESC_TYPE_16_BIT, 00218 uuidArray, 00219 descriptor->getMaxLength(), 00220 descriptor->getLength(), 00221 descriptor->getValuePtr(), 00222 CHAR_DESC_SECURITY_PERMISSION, 00223 CHAR_DESC_ACCESS_PERMISSION, 00224 GATT_NOTIFY_ATTRIBUTE_WRITE, 00225 MIN_ENCRY_KEY_SIZE, 00226 CHAR_ATTRIBUTE_LEN_IS_FIXED, 00227 &descHandle); 00228 PRINTF("Adding Descriptor descriptor handle=%d ret=%d\n\r", descHandle, ret); 00229 if(ret==(tBleStatus)0) { 00230 PRINTF("Descriptor added successfully, descriptor handle=%d\n\r", descHandle); 00231 descriptor->setHandle(descHandle); 00232 } 00233 } 00234 00235 } 00236 00237 serviceCount++; 00238 00239 //FIXME: There is no GattService pointer array in GattServer. 00240 // There should be one? (Only the user is aware of GattServices!) Report to forum. 00241 00242 return BLE_ERROR_NONE; 00243 } 00244 00245 /**************************************************************************/ 00246 /*! 00247 @brief Reads the value of a characteristic, based on char handle 00248 00249 @param[in] attributeHandle 00250 The handle of the GattCharacteristic to read from 00251 @param[in] buffer 00252 Buffer to hold the the characteristic's value 00253 (raw byte array in LSB format) 00254 @param[in] lengthP 00255 The number of bytes read into the buffer 00256 00257 @returns ble_error_t 00258 00259 @retval BLE_ERROR_NONE 00260 Everything executed properly 00261 00262 @section EXAMPLE 00263 00264 @code 00265 00266 @endcode 00267 */ 00268 /**************************************************************************/ 00269 ble_error_t BlueNRGGattServer::read(GattAttribute::Handle_t attributeHandle, uint8_t buffer[], uint16_t *lengthP) 00270 { 00271 tBleStatus ret; 00272 uint16_t charHandle = attributeHandle-BlueNRGGattServer::CHAR_VALUE_HANDLE; 00273 00274 ret = aci_gatt_read_handle_value(charHandle, *lengthP, lengthP, buffer); 00275 00276 if(ret == BLE_STATUS_SUCCESS) { 00277 return BLE_ERROR_NONE; 00278 } 00279 switch (ret) { 00280 case ERR_INVALID_HCI_CMD_PARAMS: 00281 return BLE_ERROR_INVALID_PARAM; 00282 default: 00283 return BLE_ERROR_UNSPECIFIED; 00284 } 00285 } 00286 00287 /**************************************************************************/ 00288 /*! 00289 @brief Reads the value of a characteristic, based on the connection 00290 and char handle 00291 00292 @param[in] connectionHandle 00293 The handle of the connection 00294 @param[in] attributeHandle 00295 The handle of the GattCharacteristic to write to 00296 @param[in] buffer 00297 Data to use when updating the characteristic's value 00298 (raw byte array in LSB format) 00299 @param[in] lengthP 00300 The number of bytes in buffer 00301 00302 @returns ble_error_t 00303 00304 @retval BLE_ERROR_NONE 00305 Everything executed properly 00306 00307 @section EXAMPLE 00308 00309 @code 00310 00311 @endcode 00312 */ 00313 /**************************************************************************/ 00314 ble_error_t BlueNRGGattServer::read(Gap::Handle_t connectionHandle, 00315 GattAttribute::Handle_t attributeHandle, 00316 uint8_t buffer[], 00317 uint16_t *lengthP) { 00318 00319 /* avoid compiler warnings about unused variables */ 00320 (void)connectionHandle; 00321 (void)attributeHandle; 00322 (void)buffer; 00323 (void)lengthP; 00324 00325 return BLE_ERROR_NONE; 00326 } 00327 00328 ble_error_t BlueNRGGattServer::write(Gap::Handle_t connectionHandle, 00329 GattAttribute::Handle_t, 00330 const uint8_t[], 00331 uint16_t, bool localOnly) { 00332 /* avoid compiler warnings about unused variables */ 00333 (void)connectionHandle; 00334 (void)localOnly; 00335 00336 return BLE_ERROR_NONE; 00337 } 00338 00339 ble_error_t BlueNRGGattServer::write(GattAttribute::Handle_t attributeHandle, const uint8_t buffer[], uint16_t len, bool localOnly) 00340 { 00341 /* avoid compiler warnings about unused variables */ 00342 (void)localOnly; 00343 00344 tBleStatus ret; 00345 00346 uint16_t charHandle = attributeHandle-BlueNRGGattServer::CHAR_VALUE_HANDLE; 00347 00348 PRINTF("updating bleCharacteristic valueHandle=%u,\ 00349 corresponding serviceHandle=%u len=%d\n\r", 00350 attributeHandle, bleCharHandleMap.find(charHandle)->second, len); 00351 00352 /* 00353 * If notifications (or indications) are enabled on that characteristic, a notification (or indication) 00354 * will be sent to the client after sending this command to the BlueNRG. 00355 */ 00356 ret = aci_gatt_update_char_value(bleCharHandleMap.find(charHandle)->second, charHandle, 0, len, buffer); 00357 00358 if (ret != BLE_STATUS_SUCCESS){ 00359 PRINTF("Error while updating characteristic (ret=0x%x).\n\r", ret); 00360 switch (ret) { 00361 case BLE_STATUS_INVALID_HANDLE: 00362 case BLE_STATUS_INVALID_PARAMETER: 00363 return BLE_ERROR_INVALID_PARAM; 00364 default: 00365 return BLE_STACK_BUSY; 00366 } 00367 } 00368 00369 return BLE_ERROR_NONE; 00370 } 00371 00372 /**************************************************************************/ 00373 /*! 00374 @brief Reads a value according to the handle provided 00375 00376 @param[in] attributeHandle 00377 The handle of the attribute to read from 00378 00379 @returns ble_error_t 00380 00381 @retval BLE_ERROR_NONE 00382 Everything executed properly 00383 00384 @section EXAMPLE 00385 00386 @code 00387 00388 @endcode 00389 */ 00390 /**************************************************************************/ 00391 ble_error_t BlueNRGGattServer::Read_Request_CB(uint16_t attributeHandle) 00392 { 00393 uint16_t gapConnectionHandle = BlueNRGGap::getInstance().getConnectionHandle(); 00394 00395 GattReadCallbackParams readParams; 00396 readParams.handle = attributeHandle; 00397 00398 //PRINTF("readParams.handle = %d\n\r", readParams.handle); 00399 HCIDataReadEvent(&readParams); 00400 00401 //EXIT: 00402 if(gapConnectionHandle != 0){ 00403 //PRINTF("Calling aci_gatt_allow_read\n\r"); 00404 aci_gatt_allow_read(gapConnectionHandle); 00405 } 00406 00407 return BLE_ERROR_NONE; 00408 } 00409 00410 /**************************************************************************/ 00411 /*! 00412 @brief Returns the GattCharacteristic according to the handle provided 00413 00414 @param[in] attrHandle 00415 The handle of the attribute 00416 00417 @returns ble_error_t 00418 00419 @retval BLE_ERROR_NONE 00420 Everything executed properly 00421 00422 @section EXAMPLE 00423 00424 @code 00425 00426 @endcode 00427 */ 00428 /**************************************************************************/ 00429 GattCharacteristic* BlueNRGGattServer::getCharacteristicFromHandle(uint16_t attrHandle) 00430 { 00431 GattCharacteristic *p_char = NULL; 00432 int i; 00433 uint16_t handle, handle_1; 00434 00435 PRINTF("BlueNRGGattServer::getCharacteristicFromHandle()>>Attr Handle received %d\n\r",attrHandle); 00436 for(i=0; i<characteristicCount; i++) 00437 { 00438 handle = p_characteristics[i]->getValueAttribute().getHandle()-BlueNRGGattServer::CHAR_VALUE_HANDLE; 00439 PRINTF("handle(%d)=%d\n\r", i, handle); 00440 if(i==characteristicCount-1)//Last Characteristic check 00441 { 00442 if(attrHandle>=handle) 00443 { 00444 p_char = p_characteristics[i]; 00445 PRINTF("Found Characteristic Properties 0x%x (handle=%d)\n\r",p_char->getProperties(), handle); 00446 break; 00447 } 00448 } 00449 else { 00450 handle_1 = p_characteristics[i+1]->getValueAttribute().getHandle()-BlueNRGGattServer::CHAR_VALUE_HANDLE; 00451 //Testing if attribute handle is between two Characteristic Handles 00452 if(attrHandle>=handle && attrHandle<handle_1) 00453 { 00454 p_char = p_characteristics[i]; 00455 PRINTF("Found Characteristic Properties 0x%x (handle=%d handle_1=%d)\n\r",p_char->getProperties(), handle, handle_1); 00456 break; 00457 } else continue; 00458 } 00459 } 00460 00461 return p_char; 00462 } 00463 00464 void BlueNRGGattServer::HCIDataWrittenEvent(const GattWriteCallbackParams *params) { 00465 this->handleDataWrittenEvent(params); 00466 } 00467 00468 void BlueNRGGattServer::HCIDataReadEvent(const GattReadCallbackParams *params) { 00469 PRINTF("Called HCIDataReadEvent\n\r"); 00470 this->handleDataReadEvent(params); 00471 } 00472 00473 void BlueNRGGattServer::HCIEvent(GattServerEvents::gattEvent_e type, uint16_t charHandle) { 00474 this->handleEvent(type, charHandle); 00475 } 00476 00477 void BlueNRGGattServer::HCIDataSentEvent(unsigned count) { 00478 this->handleDataSentEvent(count); 00479 } 00480 00481 00482 ble_error_t BlueNRGGattServer::initializeGATTDatabase(void) { 00483 // <TODO> 00484 return (ble_error_t)0; 00485 } 00486 00487 /**************************************************************************/ 00488 /*! 00489 @brief Clear BlueNRGGattServer's state. 00490 00491 @returns ble_error_t 00492 00493 @retval BLE_ERROR_NONE 00494 Everything executed properly 00495 */ 00496 /**************************************************************************/ 00497 ble_error_t BlueNRGGattServer::reset(void) 00498 { 00499 /* Clear all state that is from the parent, including private members */ 00500 if (GattServer::reset() != BLE_ERROR_NONE) { 00501 return BLE_ERROR_INVALID_STATE; 00502 } 00503 00504 /* Clear class members */ 00505 memset(p_characteristics, 0, sizeof(p_characteristics)); 00506 memset(bleCharacteristicHandles, 0, sizeof(bleCharacteristicHandles)); 00507 serviceCount = 0; 00508 characteristicCount = 0; 00509 00510 return BLE_ERROR_NONE; 00511 }
Generated on Thu Jul 14 2022 01:08:08 by
1.7.2
