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 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 #ifdef YOTTA_CFG_MBED_OS 00041 #include "mbed-drivers/mbed.h" 00042 #else 00043 #include "mbed.h" 00044 #endif 00045 #include "BlueNRGGap.h" 00046 #include "ble_utils.h" 00047 #include "ble_debug.h" 00048 00049 /**************************************************************************/ 00050 /*! 00051 @brief Adds a new service to the GATT table on the peripheral 00052 00053 @params[in] service 00054 Pointer to instance of the Gatt Server to add 00055 00056 @returns ble_error_t 00057 00058 @retval BLE_ERROR_NONE 00059 Everything executed properly 00060 00061 @section EXAMPLE 00062 00063 @code 00064 00065 @endcode 00066 */ 00067 /**************************************************************************/ 00068 ble_error_t BlueNRGGattServer::addService(GattService &service) 00069 { 00070 /* ToDo: Make sure we don't overflow the array, etc. */ 00071 /* ToDo: Make sure this service UUID doesn't already exist (?) */ 00072 /* ToDo: Basic validation */ 00073 00074 tBleStatus ret; 00075 uint8_t type; 00076 uint16_t short_uuid; 00077 uint8_t primary_short_uuid[2]; 00078 uint8_t primary_base_uuid[16]; 00079 uint8_t char_base_uuid[16]; 00080 const uint8_t *base_uuid; 00081 const uint8_t *base_char_uuid; 00082 00083 uint8_t charsCount = service.getCharacteristicCount(); 00084 const uint8_t available_characteristics = BLE_TOTAL_CHARACTERISTICS - characteristicCount; 00085 00086 // check that there is enough characteristics left in the 00087 // characteristic array. 00088 if (charsCount > available_characteristics) { 00089 PRINTF("charCount = %u and characteristicCount = %u\r\n", charsCount, available_characteristics); 00090 return BLE_ERROR_NO_MEM; 00091 } 00092 00093 const uint16_t maxAttrRecords = computeAttributesRecord(service); 00094 00095 type = (service.getUUID()).shortOrLong(); 00096 PRINTF("AddService(): Type:%d\n\r", type); 00097 00098 /* Add the service to the BlueNRG */ 00099 short_uuid = (service.getUUID()).getShortUUID(); 00100 STORE_LE_16(primary_short_uuid, short_uuid); 00101 00102 if(type==UUID::UUID_TYPE_LONG) { 00103 base_uuid = (service.getUUID()).getBaseUUID(); 00104 00105 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]); 00106 } 00107 00108 ret = BLE_STATUS_SUCCESS; 00109 00110 if(type==UUID::UUID_TYPE_SHORT) { 00111 ret = aci_gatt_add_serv(UUID_TYPE_16, 00112 primary_short_uuid, 00113 PRIMARY_SERVICE, 00114 maxAttrRecords/*7*/, 00115 &servHandle); 00116 PRINTF("aci_gatt_add_serv UUID_TYPE_SHORT ret=%d\n\r", ret); 00117 00118 } else if(type==UUID::UUID_TYPE_LONG) { 00119 ret = aci_gatt_add_serv(UUID_TYPE_128, 00120 primary_base_uuid, 00121 PRIMARY_SERVICE, 00122 maxAttrRecords/*7*/, 00123 &servHandle); 00124 PRINTF("aci_gatt_add_serv UUID_TYPE_LONG ret=%d\n\r", ret); 00125 } 00126 00127 switch (ret) { 00128 case BLE_STATUS_SUCCESS: 00129 break; 00130 00131 case BLE_STATUS_INVALID_PARAMETER: 00132 return BLE_ERROR_INVALID_PARAM; 00133 00134 case BLE_STATUS_OUT_OF_HANDLE: 00135 case BLE_STATUS_INSUFFICIENT_RESOURCES: 00136 case ERR_UNSPECIFIED_ERROR: 00137 return BLE_ERROR_NO_MEM; 00138 00139 case BLE_STATUS_ERROR: 00140 default: 00141 return BLE_ERROR_INTERNAL_STACK_FAILURE; 00142 } 00143 00144 00145 00146 service.setHandle(servHandle); 00147 //serviceHandleVector.push_back(servHandle); 00148 PRINTF("added servHandle handle =%u\n\r", servHandle); 00149 uint16_t bleCharacteristic; 00150 00151 //iterate to include all characteristics 00152 for (uint8_t i = 0; i < charsCount; i++) { 00153 GattCharacteristic *p_char = service.getCharacteristic(i); 00154 uint16_t char_uuid = (p_char->getValueAttribute().getUUID()).getShortUUID(); 00155 00156 uint8_t int_8_uuid[2]; 00157 STORE_LE_16(int_8_uuid, char_uuid); 00158 00159 type = (p_char->getValueAttribute().getUUID()).shortOrLong(); 00160 00161 if(type==UUID::UUID_TYPE_LONG) { 00162 base_char_uuid = (p_char->getValueAttribute().getUUID()).getBaseUUID(); 00163 #ifdef DEBUG 00164 for(uint8_t j=0; j<16; j++) { 00165 PRINTF("base_char_uuid[%d] 0x%02x ", j, base_char_uuid[j]); 00166 } 00167 PRINTF("\n\r"); 00168 #endif 00169 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]); 00170 } 00171 00172 PRINTF("Char Properties 0x%x\n\r", p_char->getProperties()); 00173 /* 00174 * Gatt_Evt_Mask -> HardCoded (0) 00175 * Encryption_Key_Size -> Hardcoded (16) 00176 * isVariable (variable length value field) -> Hardcoded (1) 00177 */ 00178 uint8_t Gatt_Evt_Mask = 0x0; 00179 00180 if((p_char->getProperties() & 00181 (GattCharacteristic::BLE_GATT_CHAR_PROPERTIES_WRITE_WITHOUT_RESPONSE| 00182 GattCharacteristic::BLE_GATT_CHAR_PROPERTIES_WRITE))) { 00183 PRINTF("Setting up Gatt GATT_NOTIFY_ATTRIBUTE_WRITE Mask\n\r"); 00184 Gatt_Evt_Mask = Gatt_Evt_Mask | GATT_NOTIFY_ATTRIBUTE_WRITE | GATT_NOTIFY_WRITE_REQ_AND_WAIT_FOR_APPL_RESP; 00185 } 00186 if((p_char->getProperties() & 00187 (GattCharacteristic::BLE_GATT_CHAR_PROPERTIES_READ| 00188 GattCharacteristic::BLE_GATT_CHAR_PROPERTIES_NOTIFY| GattCharacteristic::BLE_GATT_CHAR_PROPERTIES_INDICATE))) { 00189 PRINTF("Setting up Gatt GATT_NOTIFY_READ_REQ_AND_WAIT_FOR_APPL_RESP Mask\n\r"); 00190 Gatt_Evt_Mask = Gatt_Evt_Mask | GATT_NOTIFY_READ_REQ_AND_WAIT_FOR_APPL_RESP; 00191 } //This will support also GATT_SERVER_ATTR_READ_WRITE since it will be covered by previous if() check. 00192 00193 if(type==UUID::UUID_TYPE_SHORT) { 00194 ret = aci_gatt_add_char(service.getHandle(), 00195 UUID_TYPE_16, 00196 int_8_uuid, 00197 p_char->getValueAttribute().getMaxLength() /*2*/ /*Value Length*/, 00198 p_char->getProperties(), 00199 ATTR_PERMISSION_NONE, 00200 Gatt_Evt_Mask /*Gatt_Evt_Mask*/, 00201 16 /*Encryption_Key_Size*/, 00202 1 /*isVariable*/, 00203 &bleCharacteristic); 00204 00205 PRINTF("aci_gatt_add_char UUID_TYPE_16 props=%d MaxLength=%d ret=%d\n\r", 00206 p_char->getProperties(), p_char->getValueAttribute().getMaxLength(), ret); 00207 00208 } else if(type==UUID::UUID_TYPE_LONG) { 00209 ret = aci_gatt_add_char(service.getHandle(), 00210 UUID_TYPE_128, 00211 char_base_uuid, 00212 p_char->getValueAttribute().getMaxLength() /*2*/ /*Value Length*/, 00213 p_char->getProperties(), 00214 ATTR_PERMISSION_NONE, 00215 Gatt_Evt_Mask /*Gatt_Evt_Mask*/, 00216 16 /*Encryption_Key_Size*/, 00217 1 /*isVariable*/, 00218 &bleCharacteristic); 00219 00220 PRINTF("aci_gatt_add_char UUID_TYPE_128 props=%d MaxLength=%d ret=%d\n\r", 00221 p_char->getProperties(), p_char->getValueAttribute().getMaxLength(), ret); 00222 } 00223 00224 switch (ret) { 00225 case BLE_STATUS_SUCCESS: 00226 break; 00227 00228 case ERR_UNSPECIFIED_ERROR: 00229 case BLE_STATUS_INSUFFICIENT_RESOURCES: 00230 case BLE_STATUS_OUT_OF_HANDLE: 00231 // TODO remove characteristics and the service previously added. 00232 // remove service in the stack by using: Aci_Gatt_Del_Service 00233 // remove characteristics in the stack by using: Aci_Gatt_Del_Char 00234 // update service counter 00235 // destroy registered characteristic and updat echaracteristic counter 00236 return BLE_ERROR_NO_MEM; 00237 00238 case BLE_STATUS_INVALID_HANDLE: 00239 case BLE_STATUS_INVALID_PARAMETER: 00240 case BLE_STATUS_CHARAC_ALREADY_EXISTS: 00241 // TODO remove characteristics and the service previously added. 00242 // remove service in the stack by using: Aci_Gatt_Del_Service 00243 // remove characteristics in the stack by using: Aci_Gatt_Del_Char 00244 // update service counter 00245 // destroy registered characteristic and updat echaracteristic counter 00246 return BLE_ERROR_INVALID_PARAM; 00247 00248 case BLE_STATUS_ERROR: 00249 default: 00250 // TODO remove characteristics and the service previously added. 00251 // remove service in the stack by using: Aci_Gatt_Del_Service 00252 // remove characteristics in the stack by using: Aci_Gatt_Del_Char 00253 // update service counter 00254 // destroy registered characteristic and updat echaracteristic counter 00255 return BLE_ERROR_INTERNAL_STACK_FAILURE; 00256 } 00257 00258 bleCharHandleMap.insert(std::pair<uint16_t, uint16_t>(bleCharacteristic, servHandle)); 00259 00260 p_characteristics[characteristicCount++] = p_char; 00261 /* Set the characteristic value handle */ 00262 p_char->getValueAttribute().setHandle(bleCharacteristic+BlueNRGGattServer::CHAR_VALUE_HANDLE); 00263 PRINTF("added bleCharacteristic (value handle =%u)\n\r", p_char->getValueAttribute().getHandle()); 00264 00265 if ((p_char->getValueAttribute().getValuePtr() != NULL) && (p_char->getValueAttribute().getLength() > 0)) { 00266 ble_error_t err = write(p_char->getValueAttribute().getHandle(), 00267 p_char->getValueAttribute().getValuePtr(), 00268 p_char->getValueAttribute().getLength(), false /* localOnly */); 00269 if (err) { 00270 PRINTF("ERROR HERE !!!!\r\n"); 00271 return err; 00272 } 00273 } 00274 00275 // add descriptors now 00276 uint16_t descHandle = 0; 00277 PRINTF("p_char->getDescriptorCount()=%d\n\r", p_char->getDescriptorCount()); 00278 00279 for(uint8_t descIndex=0; descIndex<p_char->getDescriptorCount(); descIndex++) { 00280 GattAttribute *descriptor = p_char->getDescriptor(descIndex); 00281 uint8_t desc_uuid[16] = { 0 }; 00282 00283 00284 uint8_t desc_uuid_type = CHAR_DESC_TYPE_16_BIT; 00285 STORE_LE_16(desc_uuid, descriptor->getUUID().getShortUUID()); 00286 00287 if((descriptor->getUUID()).shortOrLong() == UUID::UUID_TYPE_LONG) { 00288 desc_uuid_type = CHAR_DESC_TYPE_128_BIT; 00289 const uint8_t* base_desc_uuid = descriptor->getUUID().getBaseUUID(); 00290 00291 COPY_UUID_128(desc_uuid, base_desc_uuid[15], base_desc_uuid[14],base_desc_uuid[13],base_desc_uuid[12], base_desc_uuid[11], base_desc_uuid[10], base_desc_uuid[9], base_desc_uuid[8], base_desc_uuid[7], base_desc_uuid[6], base_desc_uuid[5], base_desc_uuid[4], base_desc_uuid[3], base_desc_uuid[2], base_desc_uuid[1], base_desc_uuid[0]); 00292 } 00293 00294 ret = aci_gatt_add_char_desc(service.getHandle(), 00295 bleCharacteristic, 00296 desc_uuid_type, 00297 desc_uuid, 00298 descriptor->getMaxLength(), 00299 descriptor->getLength(), 00300 descriptor->getValuePtr(), 00301 CHAR_DESC_SECURITY_PERMISSION, 00302 CHAR_DESC_ACCESS_PERMISSION, 00303 GATT_NOTIFY_ATTRIBUTE_WRITE, 00304 MIN_ENCRY_KEY_SIZE, 00305 CHAR_ATTRIBUTE_LEN_IS_FIXED, 00306 &descHandle); 00307 PRINTF("Adding Descriptor descriptor handle=%d ret=%d\n\r", descHandle, ret); 00308 00309 switch (ret) { 00310 case BLE_STATUS_SUCCESS: 00311 PRINTF("Descriptor added successfully, descriptor handle=%d\n\r", descHandle); 00312 descriptor->setHandle(descHandle); 00313 break; 00314 00315 case ERR_UNSPECIFIED_ERROR: 00316 case BLE_STATUS_INSUFFICIENT_RESOURCES: 00317 case BLE_STATUS_OUT_OF_HANDLE: 00318 // TODO remove characteristics and the service previously added. 00319 // remove service in the stack by using: Aci_Gatt_Del_Service 00320 // remove characteristics in the stack by using: Aci_Gatt_Del_Char 00321 // update service counter 00322 // destroy registered characteristic and updat echaracteristic counter 00323 return BLE_ERROR_NO_MEM; 00324 00325 case BLE_STATUS_INVALID_HANDLE: 00326 case BLE_STATUS_INVALID_PARAMETER: 00327 // TODO remove characteristics and the service previously added. 00328 // remove service in the stack by using: Aci_Gatt_Del_Service 00329 // remove characteristics in the stack by using: Aci_Gatt_Del_Char 00330 // update service counter 00331 // destroy registered characteristic and updat echaracteristic counter 00332 return BLE_ERROR_INVALID_PARAM; 00333 00334 case BLE_STATUS_INVALID_OPERATION: 00335 return BLE_ERROR_OPERATION_NOT_PERMITTED; 00336 00337 case BLE_STATUS_ERROR: 00338 default: 00339 // TODO remove characteristics and the service previously added. 00340 // remove service in the stack by using: Aci_Gatt_Del_Service 00341 // remove characteristics in the stack by using: Aci_Gatt_Del_Char 00342 // update service counter 00343 // destroy registered characteristic and updat echaracteristic counter 00344 return BLE_ERROR_INTERNAL_STACK_FAILURE; 00345 } 00346 } 00347 } 00348 00349 serviceCount++; 00350 00351 //FIXME: There is no GattService pointer array in GattServer. 00352 // There should be one? (Only the user is aware of GattServices!) Report to forum. 00353 00354 return BLE_ERROR_NONE; 00355 } 00356 00357 /**************************************************************************/ 00358 /*! 00359 @brief Reads the value of a characteristic, based on char handle 00360 00361 @param[in] attributeHandle 00362 The handle of the GattCharacteristic to read from 00363 @param[in] buffer 00364 Buffer to hold the the characteristic's value 00365 (raw byte array in LSB format) 00366 @param[in] lengthP 00367 The number of bytes read into the buffer 00368 00369 @returns ble_error_t 00370 00371 @retval BLE_ERROR_NONE 00372 Everything executed properly 00373 00374 @section EXAMPLE 00375 00376 @code 00377 00378 @endcode 00379 */ 00380 /**************************************************************************/ 00381 ble_error_t BlueNRGGattServer::read(GattAttribute::Handle_t attributeHandle, uint8_t buffer[], uint16_t *lengthP) 00382 { 00383 tBleStatus ret; 00384 uint16_t charHandle = attributeHandle; 00385 00386 ret = aci_gatt_read_handle_value(charHandle, *lengthP, lengthP, buffer); 00387 00388 if(ret == BLE_STATUS_SUCCESS) { 00389 return BLE_ERROR_NONE; 00390 } 00391 switch (ret) { 00392 case ERR_INVALID_HCI_CMD_PARAMS: 00393 return BLE_ERROR_INVALID_PARAM; 00394 default: 00395 return BLE_ERROR_UNSPECIFIED; 00396 } 00397 } 00398 00399 /**************************************************************************/ 00400 /*! 00401 @brief Reads the value of a characteristic, based on the connection 00402 and char handle 00403 00404 @param[in] connectionHandle 00405 The handle of the connection 00406 @param[in] attributeHandle 00407 The handle of the GattCharacteristic to write to 00408 @param[in] buffer 00409 Data to use when updating the characteristic's value 00410 (raw byte array in LSB format) 00411 @param[in] lengthP 00412 The number of bytes in buffer 00413 00414 @returns ble_error_t 00415 00416 @retval BLE_ERROR_NONE 00417 Everything executed properly 00418 00419 @section EXAMPLE 00420 00421 @code 00422 00423 @endcode 00424 */ 00425 /**************************************************************************/ 00426 ble_error_t BlueNRGGattServer::read(Gap::Handle_t connectionHandle, 00427 GattAttribute::Handle_t attributeHandle, 00428 uint8_t buffer[], 00429 uint16_t *lengthP) { 00430 00431 /* avoid compiler warnings about unused variables */ 00432 (void)connectionHandle; 00433 (void)attributeHandle; 00434 (void)buffer; 00435 (void)lengthP; 00436 00437 return BLE_ERROR_NONE; 00438 } 00439 00440 ble_error_t BlueNRGGattServer::write(Gap::Handle_t connectionHandle, 00441 GattAttribute::Handle_t, 00442 const uint8_t[], 00443 uint16_t, bool localOnly) { 00444 /* avoid compiler warnings about unused variables */ 00445 (void)connectionHandle; 00446 (void)localOnly; 00447 00448 return BLE_ERROR_NONE; 00449 } 00450 00451 ble_error_t BlueNRGGattServer::write(GattAttribute::Handle_t attributeHandle, const uint8_t buffer[], uint16_t len, bool localOnly) 00452 { 00453 /* avoid compiler warnings about unused variables */ 00454 (void)localOnly; 00455 00456 // check that the len of the data to write are compatible with the characteristic 00457 GattCharacteristic* characteristic = getCharacteristicFromHandle(attributeHandle); 00458 if (!characteristic) { 00459 PRINTF("characteristic not found\r\n"); 00460 return BLE_ERROR_INVALID_PARAM; 00461 } 00462 00463 // if the attribute handle is the attribute handle of the characteristic value then 00464 // write the value 00465 if (attributeHandle == characteristic->getValueHandle()) { 00466 // assert the len in input is correct for this characteristic 00467 const GattAttribute& value_attribute = characteristic->getValueAttribute(); 00468 00469 // reject write if the lenght exceed the maximum lenght of this attribute 00470 if (value_attribute.getMaxLength() < len) { 00471 PRINTF("invalid variable length: %u, max length is: %u\r\n", len, value_attribute.getMaxLength()); 00472 return BLE_ERROR_INVALID_PARAM; 00473 } 00474 00475 // reject write if the attribute size is fixed and the lenght in input is different than the 00476 // length of the attribute. 00477 if (value_attribute.hasVariableLength() == false && value_attribute.getMaxLength() != len) { 00478 PRINTF("invalid fixed length: %u, len should be %u\r\n", len, value_attribute.getMaxLength()); 00479 return BLE_ERROR_INVALID_PARAM; 00480 } 00481 00482 tBleStatus ret; 00483 00484 uint16_t charHandle = characteristic->getValueHandle() - BlueNRGGattServer::CHAR_VALUE_HANDLE; 00485 00486 PRINTF("updating bleCharacteristic valueHandle=%u,\ 00487 corresponding serviceHandle=%u len=%d\n\r", 00488 attributeHandle, bleCharHandleMap.find(charHandle)->second, len); 00489 00490 /* 00491 * If notifications (or indications) are enabled on that characteristic, a notification (or indication) 00492 * will be sent to the client after sending this command to the BlueNRG. 00493 */ 00494 ret = aci_gatt_update_char_value(bleCharHandleMap.find(charHandle)->second, charHandle, 0, len, buffer); 00495 00496 if (ret != BLE_STATUS_SUCCESS){ 00497 PRINTF("Error while updating characteristic (ret=0x%x).\n\r", ret); 00498 switch (ret) { 00499 case BLE_STATUS_INVALID_HANDLE: 00500 case BLE_STATUS_INVALID_PARAMETER: 00501 return BLE_ERROR_INVALID_PARAM; 00502 default: 00503 return BLE_STACK_BUSY; 00504 } 00505 } 00506 00507 return BLE_ERROR_NONE; 00508 } else { 00509 // write this handle has a descriptor handle 00510 uint16_t charHandle = characteristic->getValueHandle() - BlueNRGGattServer::CHAR_VALUE_HANDLE; 00511 uint16_t service_handle = bleCharHandleMap.find(charHandle)->second; 00512 00513 tBleStatus ret = aci_gatt_set_desc_value( 00514 service_handle, 00515 charHandle, 00516 attributeHandle, 00517 0, 00518 len, 00519 buffer 00520 ); 00521 00522 if (ret != BLE_STATUS_SUCCESS){ 00523 PRINTF("Error while updating characteristic descriptor (ret=0x%x).\n\r", ret); 00524 switch (ret) { 00525 case BLE_STATUS_INVALID_HANDLE: 00526 case BLE_STATUS_INVALID_PARAMETER: 00527 return BLE_ERROR_INVALID_PARAM; 00528 default: 00529 return BLE_STACK_BUSY; 00530 } 00531 } 00532 00533 return BLE_ERROR_NONE; 00534 } 00535 } 00536 00537 /**************************************************************************/ 00538 /*! 00539 @brief Reads a value according to the handle provided 00540 00541 @param[in] attributeHandle 00542 The handle of the attribute to read from 00543 00544 @returns ble_error_t 00545 00546 @retval BLE_ERROR_NONE 00547 Everything executed properly 00548 00549 @section EXAMPLE 00550 00551 @code 00552 00553 @endcode 00554 */ 00555 /**************************************************************************/ 00556 ble_error_t BlueNRGGattServer::Read_Request_CB(uint16_t attributeHandle) 00557 { 00558 uint16_t gapConnectionHandle = BlueNRGGap::getInstance().getConnectionHandle(); 00559 00560 GattReadCallbackParams readParams; 00561 readParams.handle = attributeHandle; 00562 00563 //PRINTF("readParams.handle = %d\n\r", readParams.handle); 00564 HCIDataReadEvent(&readParams); 00565 00566 //EXIT: 00567 if(gapConnectionHandle != 0){ 00568 //PRINTF("Calling aci_gatt_allow_read\n\r"); 00569 aci_gatt_allow_read(gapConnectionHandle); 00570 } 00571 00572 return BLE_ERROR_NONE; 00573 } 00574 00575 // ask if the write request should be accepted of rejected 00576 // return 0 in case of success or an ATT error response in 00577 // case of faillure 00578 uint8_t BlueNRGGattServer::Write_Request_CB( 00579 uint16_t connection_handle, uint16_t attr_handle, uint8_t data_length, 00580 const uint8_t* data) { 00581 00582 GattCharacteristic* characteristic = getCharacteristicFromHandle(attr_handle); 00583 if(!characteristic) { 00584 return AUTH_CALLBACK_REPLY_ATTERR_INVALID_HANDLE & 0xFF; 00585 } 00586 00587 // check if the data length is in range 00588 if (characteristic->getValueAttribute().getMaxLength() < data_length) { 00589 return AUTH_CALLBACK_REPLY_ATTERR_INVALID_ATT_VAL_LENGTH & 0xFF; 00590 } 00591 00592 // if the length of the characteristic value is fixed 00593 // then the data in input should be of that length 00594 if (characteristic->getValueAttribute().hasVariableLength() == false && 00595 characteristic->getValueAttribute().getMaxLength() != data_length) { 00596 return AUTH_CALLBACK_REPLY_ATTERR_INVALID_ATT_VAL_LENGTH & 0xFF; 00597 } 00598 00599 GattWriteAuthCallbackParams params = { 00600 connection_handle, 00601 attr_handle, 00602 /* offset */ 0, 00603 data_length, 00604 data, 00605 /* authorizationReply */ AUTH_CALLBACK_REPLY_ATTERR_WRITE_NOT_PERMITTED 00606 }; 00607 00608 return characteristic->authorizeWrite(¶ms) & 0xFF; 00609 } 00610 00611 /**************************************************************************/ 00612 /*! 00613 @brief Returns the GattCharacteristic according to the handle provided 00614 00615 @param[in] attrHandle 00616 The handle of the attribute 00617 00618 @returns ble_error_t 00619 00620 @retval BLE_ERROR_NONE 00621 Everything executed properly 00622 00623 @section EXAMPLE 00624 00625 @code 00626 00627 @endcode 00628 */ 00629 /**************************************************************************/ 00630 GattCharacteristic* BlueNRGGattServer::getCharacteristicFromHandle(uint16_t attrHandle) 00631 { 00632 GattCharacteristic *p_char = NULL; 00633 int i; 00634 uint16_t handle, handle_1; 00635 00636 PRINTF("BlueNRGGattServer::getCharacteristicFromHandle()>>Attr Handle received %d\n\r",attrHandle); 00637 for(i=0; i<characteristicCount; i++) 00638 { 00639 handle = p_characteristics[i]->getValueAttribute().getHandle()-BlueNRGGattServer::CHAR_VALUE_HANDLE; 00640 PRINTF("handle(%d)=%d\n\r", i, handle); 00641 if(i==characteristicCount-1)//Last Characteristic check 00642 { 00643 if(attrHandle>=handle) 00644 { 00645 p_char = p_characteristics[i]; 00646 PRINTF("Found Characteristic Properties 0x%x (handle=%d)\n\r",p_char->getProperties(), handle); 00647 break; 00648 } 00649 } 00650 else { 00651 handle_1 = p_characteristics[i+1]->getValueAttribute().getHandle()-BlueNRGGattServer::CHAR_VALUE_HANDLE; 00652 //Testing if attribute handle is between two Characteristic Handles 00653 if(attrHandle>=handle && attrHandle<handle_1) 00654 { 00655 p_char = p_characteristics[i]; 00656 PRINTF("Found Characteristic Properties 0x%x (handle=%d handle_1=%d)\n\r",p_char->getProperties(), handle, handle_1); 00657 break; 00658 } else continue; 00659 } 00660 } 00661 00662 return p_char; 00663 } 00664 00665 void BlueNRGGattServer::HCIDataWrittenEvent(const GattWriteCallbackParams *params) { 00666 this->handleDataWrittenEvent(params); 00667 } 00668 00669 void BlueNRGGattServer::HCIDataReadEvent(const GattReadCallbackParams *params) { 00670 PRINTF("Called HCIDataReadEvent\n\r"); 00671 this->handleDataReadEvent(params); 00672 } 00673 00674 void BlueNRGGattServer::HCIEvent(GattServerEvents::gattEvent_e type, uint16_t charHandle) { 00675 this->handleEvent(type, charHandle); 00676 } 00677 00678 void BlueNRGGattServer::HCIDataSentEvent(unsigned count) { 00679 this->handleDataSentEvent(count); 00680 } 00681 00682 00683 ble_error_t BlueNRGGattServer::initializeGATTDatabase(void) { 00684 // <TODO> 00685 return (ble_error_t)0; 00686 } 00687 00688 /**************************************************************************/ 00689 /*! 00690 @brief Clear BlueNRGGattServer's state. 00691 00692 @returns ble_error_t 00693 00694 @retval BLE_ERROR_NONE 00695 Everything executed properly 00696 */ 00697 /**************************************************************************/ 00698 ble_error_t BlueNRGGattServer::reset(void) 00699 { 00700 /* Clear all state that is from the parent, including private members */ 00701 if (GattServer::reset() != BLE_ERROR_NONE) { 00702 return BLE_ERROR_INVALID_STATE; 00703 } 00704 00705 /* Clear class members */ 00706 memset(p_characteristics, 0, sizeof(p_characteristics)); 00707 memset(bleCharacteristicHandles, 0, sizeof(bleCharacteristicHandles)); 00708 serviceCount = 0; 00709 characteristicCount = 0; 00710 00711 return BLE_ERROR_NONE; 00712 } 00713 00714 00715 /// compute the number of attributes needed by this service. 00716 uint16_t BlueNRGGattServer::computeAttributesRecord(GattService& service) { 00717 uint16_t attribute_records = 1; 00718 00719 for (uint8_t characteristic_index = 0; characteristic_index < service.getCharacteristicCount(); ++characteristic_index) { 00720 // add two attributes, one for the characteristic declaration 00721 // and the other for the characteristic value. 00722 attribute_records += 2; 00723 00724 const GattCharacteristic* characteristic = service.getCharacteristic(characteristic_index); 00725 const uint8_t properties = characteristic->getProperties(); 00726 // if notify or indicate are present, two attributes are 00727 // needed 00728 if ((properties & GattCharacteristic::BLE_GATT_CHAR_PROPERTIES_NOTIFY) || 00729 (properties & GattCharacteristic::BLE_GATT_CHAR_PROPERTIES_INDICATE)) { 00730 attribute_records += 2; 00731 } 00732 00733 // if broadcast is set, two attributes are needed 00734 if (properties & GattCharacteristic::BLE_GATT_CHAR_PROPERTIES_BROADCAST) { 00735 attribute_records += 2; 00736 } 00737 00738 // if extended properties flag is set, two attributes are needed 00739 if (properties & GattCharacteristic::BLE_GATT_CHAR_PROPERTIES_EXTENDED_PROPERTIES) { 00740 attribute_records += 2; 00741 } 00742 00743 attribute_records += characteristic->getDescriptorCount(); 00744 } 00745 00746 // for some reason, if there is just a service, this value should 00747 // be equal to 5 00748 if (attribute_records == 1) { 00749 attribute_records = 5; 00750 } 00751 00752 return attribute_records; 00753 }
Generated on Thu Jul 14 2022 09:39:26 by
 1.7.2
 1.7.2 
    