BLE shield
Fork of X_NUCLEO_IDB0XA1 by
Embed:
(wiki syntax)
Show/hide line numbers
BlueNRGGattServer.cpp
Go to the documentation of this file.
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