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 00035 // ANDREA: Changed some types (e.g., tHalUint8 --> uint8_t) 00036 00037 /** @defgroup BlueNRGGATTSERVER 00038 * @brief BlueNRG BLE_API GattServer Adaptation 00039 * @{ 00040 */ 00041 00042 #include "BlueNRGGattServer.h" 00043 #include "mbed.h" 00044 #include "BlueNRGGap.h" 00045 #include "Utils.h" 00046 #include "debug.h" 00047 00048 /**************************************************************************/ 00049 /*! 00050 @brief Adds a new service to the GATT table on the peripheral 00051 00052 @params[in] service 00053 Pointer to instance of the Gatt Server to add 00054 00055 @returns ble_error_t 00056 00057 @retval BLE_ERROR_NONE 00058 Everything executed properly 00059 00060 @section EXAMPLE 00061 00062 @code 00063 00064 @endcode 00065 */ 00066 /**************************************************************************/ 00067 ble_error_t BlueNRGGattServer::addService(GattService &service) 00068 { 00069 /* ToDo: Make sure we don't overflow the array, etc. */ 00070 /* ToDo: Make sure this service UUID doesn't already exist (?) */ 00071 /* ToDo: Basic validation */ 00072 00073 tBleStatus ret; 00074 uint8_t type; 00075 uint16_t short_uuid; 00076 uint8_t primary_short_uuid[2]; 00077 uint8_t primary_base_uuid[16]; 00078 uint8_t char_base_uuid[16]; 00079 const uint8_t *base_uuid; 00080 const uint8_t *base_char_uuid; 00081 00082 uint8_t charsCount = 0; 00083 uint8_t maxAttrRecords = 0; 00084 00085 type = (service.getUUID()).shortOrLong(); 00086 PRINTF("AddService(): Type:%d\n\r", type); 00087 00088 /* Add the service to the BlueNRG */ 00089 short_uuid = (service.getUUID()).getShortUUID(); 00090 STORE_LE_16(primary_short_uuid, short_uuid); 00091 00092 if(type==UUID::UUID_TYPE_LONG) { 00093 base_uuid = (service.getUUID()).getBaseUUID(); 00094 00095 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]); 00096 } 00097 00098 charsCount = service.getCharacteristicCount(); 00099 //1(service record)+2records*char+1record*char_desc 00100 maxAttrRecords = 1+3*charsCount; 00101 00102 if(type==UUID::UUID_TYPE_SHORT) { 00103 ret = aci_gatt_add_serv(UUID_TYPE_16, 00104 primary_short_uuid, 00105 PRIMARY_SERVICE, 00106 maxAttrRecords/*7*/, 00107 &servHandle); 00108 PRINTF("aci_gatt_add_serv UUID_TYPE_LONG ret=%d\n\r", ret); 00109 } 00110 else if(type==UUID::UUID_TYPE_LONG) { 00111 ret = aci_gatt_add_serv(UUID_TYPE_128, 00112 primary_base_uuid, 00113 PRIMARY_SERVICE, 00114 maxAttrRecords/*7*/, 00115 &servHandle); 00116 PRINTF("aci_gatt_add_serv UUID_TYPE_LONG ret=%d\n\r", ret); 00117 } 00118 00119 service.setHandle(servHandle); 00120 //serviceHandleVector.push_back(servHandle); 00121 PRINTF("added servHandle handle =%u\n\r", servHandle); 00122 uint16_t bleCharacteristic; 00123 00124 //iterate to include all characteristics 00125 for (uint8_t i = 0; i < charsCount; i++) { 00126 GattCharacteristic *p_char = service.getCharacteristic(i); 00127 uint16_t char_uuid = (p_char->getValueAttribute().getUUID()).getShortUUID(); 00128 00129 uint8_t int_8_uuid[2]; 00130 STORE_LE_16(int_8_uuid, char_uuid); 00131 00132 if(type==UUID::UUID_TYPE_LONG) { 00133 base_char_uuid = (p_char->getValueAttribute().getUUID()).getBaseUUID(); 00134 00135 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]); 00136 } 00137 00138 PRINTF("Char Properties 0x%x\n\r", p_char->getProperties()); 00139 /* 00140 * Gatt_Evt_Mask -> HardCoded (0) 00141 * Encryption_Key_Size -> Hardcoded (16) 00142 * isVariable (variable length value field) -> Hardcoded (1) 00143 */ 00144 uint8_t Gatt_Evt_Mask = 0x0; 00145 00146 if((p_char->getProperties() & 00147 (GattCharacteristic::BLE_GATT_CHAR_PROPERTIES_WRITE_WITHOUT_RESPONSE| 00148 GattCharacteristic::BLE_GATT_CHAR_PROPERTIES_WRITE))) { 00149 PRINTF("Setting up Gatt GATT_NOTIFY_ATTRIBUTE_WRITE Mask\n\r"); 00150 Gatt_Evt_Mask = Gatt_Evt_Mask | GATT_NOTIFY_ATTRIBUTE_WRITE; 00151 } 00152 if((p_char->getProperties() & 00153 (GattCharacteristic::BLE_GATT_CHAR_PROPERTIES_READ| 00154 GattCharacteristic::BLE_GATT_CHAR_PROPERTIES_NOTIFY| GattCharacteristic::BLE_GATT_CHAR_PROPERTIES_INDICATE))) { 00155 PRINTF("Setting up Gatt GATT_NOTIFY_READ_REQ_AND_WAIT_FOR_APPL_RESP Mask\n\r"); 00156 Gatt_Evt_Mask = Gatt_Evt_Mask | GATT_NOTIFY_READ_REQ_AND_WAIT_FOR_APPL_RESP; 00157 } //This will support also GATT_SERVER_ATTR_READ_WRITE since it will be covered by previous if() check. 00158 00159 if(type==UUID::UUID_TYPE_SHORT) { 00160 ret = aci_gatt_add_char(service.getHandle(), 00161 UUID_TYPE_16, 00162 int_8_uuid, 00163 p_char->getValueAttribute().getMaxLength() /*2*/ /*Value Length*/, 00164 p_char->getProperties(), 00165 ATTR_PERMISSION_NONE, 00166 Gatt_Evt_Mask /*Gatt_Evt_Mask*/, 00167 16 /*Encryption_Key_Size*/, 00168 1 /*isVariable*/, 00169 &bleCharacteristic); 00170 00171 PRINTF("aci_gatt_add_char UUID_TYPE_16 props=%d MaxLength=%d ret=%d\n\r", p_char->getProperties(), p_char->getValueAttribute().getMaxLength(), ret); 00172 00173 } else if(type==UUID::UUID_TYPE_LONG) { 00174 ret = aci_gatt_add_char(service.getHandle(), 00175 UUID_TYPE_128, 00176 char_base_uuid, 00177 p_char->getValueAttribute().getMaxLength() /*2*/ /*Value Length*/, 00178 p_char->getProperties(), 00179 ATTR_PERMISSION_NONE, 00180 Gatt_Evt_Mask /*Gatt_Evt_Mask*/, 00181 16 /*Encryption_Key_Size*/, 00182 1 /*isVariable*/, 00183 &bleCharacteristic); 00184 00185 PRINTF("aci_gatt_add_char UUID_TYPE_128 props=%d MaxLength=%d ret=%d\n\r", p_char->getProperties(), p_char->getValueAttribute().getMaxLength(), ret); 00186 } 00187 00188 /* Update the characteristic handle */ 00189 //uint16_t charHandle = characteristicCount; 00190 00191 bleCharHanldeMap.insert(std::pair<uint16_t, uint16_t>(bleCharacteristic, servHandle)); 00192 00193 p_characteristics[characteristicCount++] = p_char; 00194 p_char->getValueAttribute().setHandle(bleCharacteristic); //Set the characteristic count as the corresponding char handle 00195 PRINTF("added bleCharacteristic handle =%u\n\r", bleCharacteristic); 00196 00197 if ((p_char->getValueAttribute().getValuePtr() != NULL) && (p_char->getValueAttribute().getLength() > 0)) { 00198 write(p_char->getValueAttribute().getHandle(), p_char->getValueAttribute().getValuePtr(), p_char->getValueAttribute().getLength(), false /* localOnly */); 00199 } 00200 00201 // add descriptors now 00202 uint16_t descHandle = 0; 00203 PRINTF("p_char->getDescriptorCount()=%d\n\r", p_char->getDescriptorCount()); 00204 00205 for(uint8_t descIndex=0; descIndex<p_char->getDescriptorCount(); descIndex++) { 00206 GattAttribute *descriptor = p_char->getDescriptor(descIndex); 00207 uint16_t shortUUID = descriptor->getUUID().getShortUUID(); 00208 const uint8_t uuidArray[] = {(uint8_t)((shortUUID>>8)&0xFF), (uint8_t)((shortUUID&0xFF))}; 00209 ret = aci_gatt_add_char_desc(service.getHandle(), p_char->getValueAttribute().getHandle(), 00210 CHAR_DESC_TYPE_16_BIT, uuidArray, descriptor->getMaxLength(), descriptor->getLength(), 00211 descriptor->getValuePtr(), CHAR_DESC_SECURITY_PERMISSION, CHAR_DESC_ACCESS_PERMISSION, GATT_NOTIFY_ATTRIBUTE_WRITE, 00212 MIN_ENCRY_KEY_SIZE, CHAR_ATTRIBUTE_LEN_IS_FIXED, &descHandle); 00213 PRINTF("Adding Descriptor descriptor handle=%d ret=%d\n\r", descHandle, ret); 00214 if(ret==(tBleStatus)0) { 00215 PRINTF("Descriptor added successfully, descriptor handle=%d\n\r", descHandle); 00216 descriptor->setHandle(descHandle); 00217 } 00218 } 00219 00220 } 00221 00222 serviceCount++; 00223 00224 //FIXME: There is no GattService pointer array in GattServer. 00225 // There should be one? (Only the user is aware of GattServices!) Report to forum. 00226 00227 return BLE_ERROR_NONE; 00228 } 00229 00230 /**************************************************************************/ 00231 /*! 00232 @brief Reads the value of a characteristic, based on the service 00233 and characteristic index fields 00234 00235 @param[in] charHandle 00236 The handle of the GattCharacteristic to read from 00237 @param[in] buffer 00238 Buffer to hold the the characteristic's value 00239 (raw byte array in LSB format) 00240 @param[in] lengthP 00241 The number of bytes read into the buffer 00242 00243 @returns ble_error_t 00244 00245 @retval BLE_ERROR_NONE 00246 Everything executed properly 00247 00248 @section EXAMPLE 00249 00250 @code 00251 00252 @endcode 00253 */ 00254 /**************************************************************************/ 00255 ble_error_t BlueNRGGattServer::read(GattAttribute::Handle_t charHandle, uint8_t buffer[], uint16_t *lengthP) 00256 { 00257 tBleStatus ret; 00258 00259 ret = aci_gatt_read_handle_value(charHandle+CHAR_VALUE_OFFSET, *lengthP, lengthP, buffer); 00260 00261 if(ret == BLE_STATUS_SUCCESS) { 00262 return BLE_ERROR_NONE; 00263 } 00264 switch (ret) { 00265 case ERR_INVALID_HCI_CMD_PARAMS: 00266 return BLE_ERROR_INVALID_PARAM; 00267 default: 00268 return BLE_ERROR_UNSPECIFIED; 00269 } 00270 } 00271 00272 /**************************************************************************/ 00273 /*! 00274 @brief Updates the value of a characteristic, based on the service 00275 and characteristic index fields 00276 00277 @param[in] charHandle 00278 The handle of the GattCharacteristic to write to 00279 @param[in] buffer 00280 Data to use when updating the characteristic's value 00281 (raw byte array in LSB format) 00282 @param[in] len 00283 The number of bytes in buffer 00284 00285 @returns ble_error_t 00286 00287 @retval BLE_ERROR_NONE 00288 Everything executed properly 00289 00290 @section EXAMPLE 00291 00292 @code 00293 00294 @endcode 00295 */ 00296 /**************************************************************************/ 00297 // <<<ANDREA>>> 00298 ble_error_t BlueNRGGattServer::read(Gap::Handle_t connectionHandle, GattAttribute::Handle_t attributeHandle, uint8_t buffer[], uint16_t *lengthP) { 00299 00300 /* avoid compiler warnings about unused variables */ 00301 (void)connectionHandle; 00302 (void)attributeHandle; 00303 (void)buffer; 00304 (void)lengthP; 00305 00306 return BLE_ERROR_NONE; 00307 } 00308 00309 ble_error_t BlueNRGGattServer::write(Gap::Handle_t connectionHandle, GattAttribute::Handle_t, const uint8_t[], uint16_t, bool localOnly) { 00310 /* avoid compiler warnings about unused variables */ 00311 (void)connectionHandle; 00312 (void)localOnly; 00313 00314 return BLE_ERROR_NONE; 00315 } 00316 00317 ble_error_t BlueNRGGattServer::write(GattAttribute::Handle_t charHandle, const uint8_t buffer[], uint16_t len, bool localOnly) 00318 { 00319 /* avoid compiler warnings about unused variables */ 00320 (void)localOnly; 00321 00322 tBleStatus ret; 00323 //uint8_t buff[2]; 00324 00325 PRINTF("updating bleCharacteristic charHandle =%u, corresponding serviceHanle= %u len=%d\n\r", charHandle, bleCharHanldeMap.find(charHandle)->second, len); 00326 /* 00327 for(int i=0; i<len; i++) { 00328 PRINTF("buffer[%d]=%d\n\r", i, buffer[i]); 00329 } 00330 */ 00331 ret = aci_gatt_update_char_value(bleCharHanldeMap.find(charHandle)->second, charHandle, 0, len, buffer); 00332 00333 if (ret != BLE_STATUS_SUCCESS){ 00334 PRINTF("Error while updating characteristic (ret=0x%x).\n\r", ret); 00335 switch (ret) { 00336 case BLE_STATUS_INVALID_HANDLE: 00337 case BLE_STATUS_INVALID_PARAMETER: 00338 return BLE_ERROR_INVALID_PARAM; 00339 default: 00340 return BLE_STACK_BUSY; 00341 } 00342 } 00343 00344 //Generate Data Sent Event Here? (GattServerEvents::GATT_EVENT_DATA_SENT) //FIXME: Is this correct? 00345 //Check if characteristic property is NOTIFY|INDICATE, if yes generate event 00346 GattCharacteristic *p_char = BlueNRGGattServer::getInstance().getCharacteristicFromHandle(charHandle); 00347 if(p_char->getProperties() & (GattCharacteristic::BLE_GATT_CHAR_PROPERTIES_NOTIFY 00348 | GattCharacteristic::BLE_GATT_CHAR_PROPERTIES_INDICATE)) { 00349 PRINTF("Generate event after updating\n\r"); 00350 BlueNRGGattServer::getInstance().handleEvent(GattServerEvents::GATT_EVENT_DATA_SENT, charHandle); 00351 } 00352 00353 return BLE_ERROR_NONE; 00354 } 00355 00356 /**************************************************************************/ 00357 /*! 00358 @brief Reads a value according to the handle provided 00359 00360 @param[in] charHandle 00361 The handle of the GattCharacteristic to read from 00362 00363 @returns ble_error_t 00364 00365 @retval BLE_ERROR_NONE 00366 Everything executed properly 00367 00368 @section EXAMPLE 00369 00370 @code 00371 00372 @endcode 00373 */ 00374 /**************************************************************************/ 00375 ble_error_t BlueNRGGattServer::Read_Request_CB(uint16_t handle) 00376 { 00377 //signed short refvalue; 00378 uint16_t gapConnectionHandle = BlueNRGGap::getInstance().getConnectionHandle(); 00379 00380 GattReadCallbackParams readParams; 00381 readParams.handle = handle; 00382 00383 //PRINTF("readParams.charHandle = %d\n\r", readParams.charHandle); 00384 HCIDataReadEvent(&readParams); 00385 00386 //EXIT: 00387 if(gapConnectionHandle != 0){ 00388 //PRINTF("Calling aci_gatt_allow_read\n\r"); 00389 aci_gatt_allow_read(gapConnectionHandle); 00390 } 00391 00392 return BLE_ERROR_NONE; 00393 } 00394 00395 /**************************************************************************/ 00396 /*! 00397 @brief Returns the GattCharacteristic according to the handle provided 00398 00399 @param[in] charHandle 00400 The handle of the GattCharacteristic 00401 00402 @returns ble_error_t 00403 00404 @retval BLE_ERROR_NONE 00405 Everything executed properly 00406 00407 @section EXAMPLE 00408 00409 @code 00410 00411 @endcode 00412 */ 00413 /**************************************************************************/ 00414 GattCharacteristic* BlueNRGGattServer::getCharacteristicFromHandle(uint16_t attrHandle) 00415 { 00416 GattCharacteristic *p_char = NULL; 00417 int i; 00418 uint16_t handle, handle_1; 00419 00420 PRINTF("BlueNRGGattServer::getCharacteristicFromHandle()>>Attribute Handle received %d\n\r",attrHandle); 00421 for(i=0; i<characteristicCount; i++) 00422 { 00423 handle = p_characteristics[i]->getValueAttribute().getHandle(); 00424 PRINTF("handle(%d)=%d\n\r", i, handle); 00425 if(i==characteristicCount-1)//Last Characteristic check 00426 { 00427 if(attrHandle>=handle) 00428 { 00429 p_char = p_characteristics[i]; 00430 PRINTF("Found Characteristic Properties 0x%x (handle=%d)\n\r",p_char->getProperties(), handle); 00431 break; 00432 } 00433 } 00434 else { 00435 handle_1 = p_characteristics[i+1]->getValueAttribute().getHandle(); 00436 //Testing if attribute handle is between two Characteristic Handles 00437 if(attrHandle>=handle && attrHandle<handle_1) 00438 { 00439 p_char = p_characteristics[i]; 00440 PRINTF("Found Characteristic Properties 0x%x (handle=%d handle_1=%d)\n\r",p_char->getProperties(), handle, handle_1); 00441 break; 00442 } else continue; 00443 } 00444 } 00445 00446 return p_char; 00447 } 00448 00449 void BlueNRGGattServer::HCIDataWrittenEvent(const GattWriteCallbackParams *params) { 00450 this->handleDataWrittenEvent(params); 00451 } 00452 00453 void BlueNRGGattServer::HCIDataReadEvent(const GattReadCallbackParams *params) { 00454 PRINTF("Called HCIDataReadEvent\n\r"); 00455 this->handleDataReadEvent(params); 00456 } 00457 00458 void BlueNRGGattServer::HCIEvent(GattServerEvents::gattEvent_e type, uint16_t charHandle) { 00459 this->handleEvent(type, charHandle); 00460 } 00461 00462 void BlueNRGGattServer::HCIDataSentEvent(unsigned count) { 00463 this->handleDataSentEvent(count); 00464 } 00465 00466 00467 ble_error_t BlueNRGGattServer::initializeGATTDatabase(void) { 00468 // <TODO> 00469 return (ble_error_t)0; 00470 }
Generated on Tue Jul 12 2022 19:27:28 by
1.7.2
