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.
BlueNRGGattConnectionClient.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 BlueNRGGattConnectionClient 00035 * @brief BlueNRG GattConnectionClient Adaptation 00036 * @{ 00037 */ 00038 00039 #include "BlueNRGGattConnectionClient.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 "BlueNRGGattClient.h" 00047 #include "ble_utils.h" 00048 #include "ble_debug.h" 00049 00050 // #define PRINTF printf 00051 00052 static uint8_t props_mask[] = { 00053 0x01, 00054 0x02, 00055 0x04, 00056 0x08, 00057 0x10, 00058 0x20, 00059 0x40, 00060 0x80 00061 }; 00062 00063 void BlueNRGGattConnectionClient::gattProcedureCompleteCB(uint8_t error_code) 00064 { 00065 if(error_code != BLE_STATUS_SUCCESS) { 00066 _currentState = GATT_IDLE; 00067 return; 00068 } 00069 00070 // Service Discovery complete 00071 /* 00072 if(_currentState != GATT_IDLE && 00073 _currentState != GATT_DISCOVERY_TERMINATED && 00074 _currentState != GATT_WRITE_CHAR && 00075 _currentState != GATT_READ_CHAR) { 00076 */ 00077 if(_currentState == GATT_SERVICE_DISCOVERY) { 00078 findServiceChars(); 00079 return; 00080 } 00081 00082 if(_currentState == GATT_CHAR_DESC_DISCOVERY) { 00083 _currentState = GATT_IDLE; 00084 if(charDescTerminationCallback != NULL) { 00085 CharacteristicDescriptorDiscovery::TerminationCallbackParams_t params = { 00086 _characteristic, 00087 BLE_ERROR_NONE 00088 }; 00089 charDescTerminationCallback(¶ms); 00090 } 00091 return; 00092 } 00093 00094 // Read complete 00095 if(_currentState == GATT_READ_CHAR) { 00096 _currentState = GATT_IDLE; 00097 BlueNRGGattClient::getInstance().processReadResponse(&readCBParams); 00098 free((void*)(readCBParams.data)); 00099 readCBParams.data = NULL; 00100 return; 00101 } 00102 00103 // Write complete 00104 if(_currentState == GATT_WRITE_CHAR) { 00105 _currentState = GATT_IDLE; 00106 BlueNRGGattClient::getInstance().processWriteResponse(&writeCBParams); 00107 return; 00108 } 00109 } 00110 00111 void BlueNRGGattConnectionClient::primaryServicesCB(uint8_t event_data_length, 00112 uint8_t attribute_data_length, 00113 uint8_t *attribute_data_list) 00114 { 00115 GattAttribute::Handle_t startHandle, endHandle; 00116 UUID uuid; 00117 uint8_t i, offset, numAttr; 00118 00119 numAttr = (event_data_length - 1) / attribute_data_length; 00120 00121 offset = 0; 00122 for (i=0; i<numAttr; i++) { 00123 startHandle = attribute_data_list[offset]; 00124 endHandle = attribute_data_list[offset+2]; 00125 00126 // UUID Type 00127 if (attribute_data_length == 6) { 00128 00129 PRINTF("UUID_TYPE_16\n\r"); 00130 uuid = attribute_data_list[offset+5]<<8|attribute_data_list[offset+4]; 00131 PRINTF("S UUID-%X attrs[%u %u]\r\n", uuid.getShortUUID(), startHandle, endHandle); 00132 00133 } else { 00134 00135 PRINTF("UUID_TYPE_128\n\r"); 00136 uuid.setupLong(attribute_data_list+offset+4, UUID::LSB); 00137 00138 #ifdef DEBUG 00139 PRINTF("S UUID-"); 00140 const uint8_t *longUUIDBytes = uuid.getBaseUUID(); 00141 for (unsigned j = 0; j < UUID::LENGTH_OF_LONG_UUID; j++) { 00142 PRINTF("%02x", longUUIDBytes[j]); 00143 } 00144 #endif 00145 PRINTF(" attrs[%u %u]\r\n", startHandle, endHandle); 00146 00147 } 00148 00149 PRINTF("Setup serviceIndex = %d\n\r", _numServices); 00150 discoveredService[_numServices].setup(uuid, startHandle, endHandle); 00151 00152 _numServices++; 00153 00154 offset += attribute_data_length; 00155 } 00156 00157 PRINTF("!!!Service Discovery complete (numAttr=%u)!!!\n\r", numAttr); 00158 00159 } 00160 00161 void BlueNRGGattConnectionClient::primaryServiceCB(uint8_t event_data_length, uint8_t *handles_info_list) 00162 { 00163 GattAttribute::Handle_t startHandle, endHandle; 00164 UUID uuid; 00165 uint8_t i, offset, numHandlePairs; 00166 00167 numHandlePairs = (event_data_length - 1) / 2; 00168 00169 offset = 0; 00170 for (i=0; i<numHandlePairs; i++) { 00171 startHandle = handles_info_list[offset]; 00172 endHandle = handles_info_list[offset+2]; 00173 00174 PRINTF("primaryServiceCB attrs[%u %u]\r\n", startHandle, endHandle); 00175 00176 00177 if (_matchingServiceUUID.shortOrLong() == UUID::UUID_TYPE_SHORT) { 00178 PRINTF("S UUID-%x attrs[%u %u]\r\n", _matchingServiceUUID.getShortUUID(), startHandle, endHandle); 00179 uuid = _matchingServiceUUID.getShortUUID(); 00180 } else { 00181 #ifdef DEBUG 00182 PRINTF("S UUID-"); 00183 const uint8_t *longUUIDBytes = _matchingServiceUUID.getBaseUUID(); 00184 for (unsigned i = 0; i < UUID::LENGTH_OF_LONG_UUID; i++) { 00185 PRINTF("%02x", longUUIDBytes[i]); 00186 } 00187 #endif 00188 PRINTF(" attrs[%u %u]\r\n", startHandle, endHandle); 00189 uuid.setupLong(_matchingServiceUUID.getBaseUUID(), UUID::MSB); 00190 } 00191 00192 discoveredService[i].setup(uuid, startHandle, endHandle); 00193 00194 _numServices++; 00195 00196 offset += 4; 00197 } 00198 } 00199 00200 void BlueNRGGattConnectionClient::serviceCharsCB(uint8_t event_data_length, 00201 uint8_t handle_value_pair_length, 00202 uint8_t *handle_value_pair) 00203 { 00204 // Charac Handle (2), Charac Properties(1), Charac Value Handle(2), Charac UUID(2/16) 00205 00206 GattAttribute::Handle_t declHandle, valueHandle, lastHandle; 00207 UUID uuid; 00208 uint8_t i, numChar, offset; 00209 00210 numChar = (event_data_length - 1) / handle_value_pair_length; 00211 00212 PRINTF("event_data_length=%d handle_value_pair_length=%d numChar=%d\n\r", event_data_length, handle_value_pair_length, numChar); 00213 00214 offset = 0; 00215 for (i=0; i<numChar; i++) { 00216 // UUID Type 00217 if (handle_value_pair_length == 7) { 00218 PRINTF("Char UUID_TYPE_16\n\r"); 00219 uuid = handle_value_pair[offset+6]<<8|handle_value_pair[offset+5]; 00220 PRINTF("C UUID-%X\r\n", uuid.getShortUUID()); 00221 } else { 00222 PRINTF("Char UUID_TYPE_128\n\r"); 00223 uuid.setupLong(handle_value_pair+offset+5, UUID::LSB); 00224 #ifdef DEBUG 00225 PRINTF("C UUID-"); 00226 const uint8_t *longUUIDBytes = uuid.getBaseUUID(); 00227 for (unsigned i = 0; i < UUID::LENGTH_OF_LONG_UUID; i++) { 00228 PRINTF("%02X", longUUIDBytes[i]); 00229 } 00230 PRINTF("\r\n"); 00231 #endif 00232 } 00233 00234 // Properties 00235 DiscoveredCharacteristic::Properties_t p; 00236 00237 p._broadcast = (props_mask[0] & handle_value_pair[offset+2]); 00238 p._read = (props_mask[1] & handle_value_pair[offset+2])>>1; 00239 p._writeWoResp = (props_mask[2] & handle_value_pair[offset+2])>>2; 00240 p._write = (props_mask[3] & handle_value_pair[offset+2])>>3; 00241 p._notify = (props_mask[4] & handle_value_pair[offset+2])>>4; 00242 p._indicate = (props_mask[5] & handle_value_pair[offset+2])>>5; 00243 p._authSignedWrite = (props_mask[6] & handle_value_pair[offset+2])>>6; 00244 PRINTF("p._broadcast=%d\n\r", p._broadcast); 00245 PRINTF("p._read=%d\n\r", p._read); 00246 PRINTF("p._writeWoResp=%d\n\r", p._writeWoResp); 00247 PRINTF("p._write=%d\n\r", p._write); 00248 PRINTF("p._notify=%d\n\r", p._notify); 00249 PRINTF("p._indicate=%d\n\r", p._indicate); 00250 PRINTF("p._authSignedWrite=%d\n\r", p._authSignedWrite); 00251 00252 /* 00253 uint8_t props = handle_value_pair[offset+2]; 00254 PRINTF("CHAR PROPS: %d\n\r", props); 00255 */ 00256 00257 // Handles 00258 declHandle = handle_value_pair[offset]; 00259 valueHandle = handle_value_pair[offset+3]; 00260 lastHandle = valueHandle+1; 00261 PRINTF("declHandle: %u valueHandle=%u lastHandle=%u\n\r", declHandle, valueHandle, lastHandle); 00262 00263 discoveredChar[_numChars].setup(_gattClient, 00264 _connectionHandle, 00265 uuid, 00266 p, 00267 declHandle, 00268 valueHandle, 00269 lastHandle); 00270 00271 if (_numChars != 0) { 00272 discoveredChar[_numChars - 1].setLastHandle(declHandle - 1); 00273 00274 if(characteristicDiscoveryCallback) { 00275 characteristicDiscoveryCallback(&discoveredChar[_numChars - 1]); 00276 } 00277 } 00278 00279 _numChars++; 00280 00281 offset += handle_value_pair_length; 00282 } 00283 } 00284 00285 void BlueNRGGattConnectionClient::serviceCharByUUIDCB(uint8_t event_data_length, 00286 uint16_t attr_handle, 00287 uint8_t *attr_value) 00288 { 00289 // Charac Properties(1), Charac Value Handle(2), Charac UUID(2/16) 00290 GattAttribute::Handle_t declHandle, valueHandle, lastHandle; 00291 UUID uuid; 00292 00293 PRINTF("serviceCharByUUIDCB\n\r"); 00294 00295 // UUID Type 00296 if (event_data_length == 7) { 00297 PRINTF("Char UUID_TYPE_16\n\r"); 00298 uuid = attr_value[4]<<8|attr_value[3]; 00299 PRINTF("C UUID-%X\r\n", uuid.getShortUUID()); 00300 } else { 00301 PRINTF("Char UUID_TYPE_128\n\r"); 00302 uuid.setupLong(attr_value+3, UUID::LSB); 00303 #ifdef DEBUG 00304 PRINTF("C UUID-"); 00305 const uint8_t *longUUIDBytes = uuid.getBaseUUID(); 00306 for (unsigned i = 0; i < UUID::LENGTH_OF_LONG_UUID; i++) { 00307 PRINTF("%02X", longUUIDBytes[i]); 00308 } 00309 PRINTF("\r\n"); 00310 #endif 00311 } 00312 00313 // Properties 00314 DiscoveredCharacteristic::Properties_t p; 00315 00316 p._broadcast = (props_mask[0] & attr_value[0]); 00317 p._read = (props_mask[1] & attr_value[0])>>1; 00318 p._writeWoResp = (props_mask[2] & attr_value[0])>>2; 00319 p._write = (props_mask[3] & attr_value[0])>>3; 00320 p._notify = (props_mask[4] & attr_value[0])>>4; 00321 p._indicate = (props_mask[5] & attr_value[0])>>5; 00322 p._authSignedWrite = (props_mask[6] & attr_value[0])>>6; 00323 PRINTF("p._broadcast=%d\n\r", p._broadcast); 00324 PRINTF("p._read=%d\n\r", p._read); 00325 PRINTF("p._writeWoResp=%d\n\r", p._writeWoResp); 00326 PRINTF("p._write=%d\n\r", p._write); 00327 PRINTF("p._notify=%d\n\r", p._notify); 00328 PRINTF("p._indicate=%d\n\r", p._indicate); 00329 PRINTF("p._authSignedWrite=%d\n\r", p._authSignedWrite); 00330 00331 /* 00332 uint8_t props = attr_value[0]; 00333 PRINTF("CHAR PROPS: %d\n\r", props); 00334 */ 00335 00336 // Handles 00337 declHandle = attr_handle; 00338 valueHandle = attr_value[1]; 00339 lastHandle = valueHandle+1; 00340 00341 discoveredChar[_numChars].setup(_gattClient, 00342 _connectionHandle, 00343 uuid, 00344 p, 00345 declHandle, 00346 valueHandle, 00347 lastHandle); 00348 00349 // update the last handle and call the characteristic discovery callback for previous char 00350 if (_numChars != 0) { 00351 discoveredChar[_numChars - 1].setLastHandle(declHandle - 1); 00352 00353 if(characteristicDiscoveryCallback) { 00354 characteristicDiscoveryCallback(&discoveredChar[_numChars - 1]); 00355 } 00356 } 00357 00358 _numChars++; 00359 } 00360 00361 ble_error_t BlueNRGGattConnectionClient::findServiceChars(void) 00362 { 00363 PRINTF("findServiceChars\n\r"); 00364 00365 tBleStatus ret; 00366 uint8_t uuid_type = UUID_TYPE_16; 00367 uint8_t short_uuid[2]; 00368 uint8_t *uuid = NULL; 00369 00370 DiscoveredService *service; 00371 00372 // complete the discovery of the last characteristic of the previous service. 00373 // Its last handle wasn't known before this point 00374 // update the handle and call the characteristic discovery callback. 00375 if (_servIndex != 0 && _numChars != 0) { 00376 discoveredChar[_numChars - 1].setLastHandle(discoveredService[_servIndex - 1].getEndHandle()); 00377 00378 if(characteristicDiscoveryCallback) { 00379 characteristicDiscoveryCallback(&discoveredChar[_numChars - 1]); 00380 } 00381 } 00382 00383 _numChars = 0; 00384 00385 // We finished chars discovery for all services 00386 if(_servIndex >= _numServices) { 00387 PRINTF("!!!We finished chars discovery for all services!!!\n\r"); 00388 //_currentState = GATT_CHARS_DISCOVERY_COMPLETE; 00389 00390 terminateServiceDiscovery(); 00391 00392 return BLE_ERROR_NONE; 00393 } 00394 00395 service = &discoveredService[_servIndex]; 00396 /* 00397 if (service->getUUID().shortOrLong() == UUID::UUID_TYPE_SHORT) { 00398 PRINTF("S UUID-%X\r\n", service->getUUID().getShortUUID()); 00399 } else { 00400 PRINTF("S UUID-"); 00401 const uint8_t *longUUIDBytes = service->getUUID().getBaseUUID(); 00402 for (unsigned i = 0; i < UUID::LENGTH_OF_LONG_UUID; i++) { 00403 PRINTF("%02X", longUUIDBytes[i]); 00404 } 00405 PRINTF("\r\n"); 00406 } 00407 */ 00408 00409 if(serviceDiscoveryCallback) { 00410 serviceDiscoveryCallback(service); 00411 } 00412 00413 PRINTF("findServiceChars (_servIndex=%d)\n\r", _servIndex); 00414 //ret = aci_gatt_disc_all_charac_of_serv(connectionHandle, service->getStartHandle(), service->getEndHandle()); 00415 00416 if(_matchingCharacteristicUUIDIn == BLE_UUID_UNKNOWN) { 00417 PRINTF("findServiceChars (BLE_UUID_UNKNOWN)\n\r"); 00418 ret = aci_gatt_disc_all_charac_of_serv(_connectionHandle, service->getStartHandle(), service->getEndHandle()); 00419 } else { 00420 00421 uint8_t type = _matchingCharacteristicUUIDIn.shortOrLong(); 00422 00423 if(type == UUID::UUID_TYPE_SHORT) { 00424 STORE_LE_16(short_uuid, _matchingCharacteristicUUIDIn.getShortUUID()); 00425 00426 uuid_type = UUID_TYPE_16; 00427 uuid = short_uuid; 00428 #ifdef DEBUG 00429 PRINTF("findServiceChars C UUID-"); 00430 for(unsigned i = 0; i < 2; i++) { 00431 PRINTF("%02X", short_uuid[i]); 00432 } 00433 PRINTF("\n\r"); 00434 #endif 00435 } else if(type==UUID::UUID_TYPE_LONG) { 00436 00437 uuid_type = UUID_TYPE_128; 00438 uuid = (unsigned char*)_matchingCharacteristicUUIDIn.getBaseUUID(); 00439 #ifdef DEBUG 00440 PRINTF("(findServiceChars) C UUID-"); 00441 for (unsigned i = 0; i < UUID::LENGTH_OF_LONG_UUID; i++) { 00442 PRINTF("%02X", uuid[i]); 00443 } 00444 PRINTF("\r\n"); 00445 #endif 00446 } 00447 00448 ret = aci_gatt_disc_charac_by_uuid(_connectionHandle, 00449 service->getStartHandle(), 00450 service->getEndHandle(), 00451 uuid_type, 00452 uuid); 00453 } 00454 00455 if(ret == BLE_STATUS_SUCCESS) { 00456 _servIndex++; 00457 } 00458 00459 PRINTF("findServiceChars ret=%d\n\r", ret); 00460 00461 return BLE_ERROR_NONE; 00462 } 00463 00464 ble_error_t BlueNRGGattConnectionClient::launchServiceDiscovery(ServiceDiscovery::ServiceCallback_t sc, 00465 ServiceDiscovery::CharacteristicCallback_t cc, 00466 const UUID &matchingServiceUUID, 00467 const UUID &matchingCharacteristicUUIDIn) 00468 { 00469 PRINTF("BlueNRGGattConnectionClient launchServiceDiscovery\n\r"); 00470 00471 tBleStatus ret; 00472 uint8_t uuid_type = UUID_TYPE_16; 00473 uint8_t short_uuid[2]; 00474 uint8_t *uuid = NULL; 00475 unsigned j; 00476 00477 if(isServiceDiscoveryActive()) { 00478 return BLE_ERROR_OPERATION_NOT_PERMITTED; 00479 } 00480 00481 if(!sc && !cc) { 00482 // nothing to do 00483 PRINTF("BlueNRGGattConnectionClient launchServiceDiscovery: nothing to do\n\r"); 00484 return BLE_ERROR_NONE; 00485 } 00486 00487 serviceDiscoveryCallback = sc; 00488 characteristicDiscoveryCallback = cc; 00489 _matchingServiceUUID = matchingServiceUUID; 00490 _matchingCharacteristicUUIDIn = matchingCharacteristicUUIDIn; 00491 00492 //reset services 00493 _numServices = 0; 00494 _numChars = 0; 00495 _servIndex = 0; 00496 for(j = 0; j < BLE_TOTAL_DISCOVERED_SERVICES; j++) { 00497 discoveredService[j].setup(BLE_UUID_UNKNOWN, GattAttribute::INVALID_HANDLE, GattAttribute::INVALID_HANDLE); 00498 } 00499 00500 if(matchingServiceUUID == BLE_UUID_UNKNOWN) { 00501 00502 // Wildcard: search for all services 00503 PRINTF("Wildcard: search for all services\r\n"); 00504 ret = aci_gatt_disc_all_prim_services((uint16_t)_connectionHandle); 00505 00506 } else { 00507 PRINTF("search for specific services\r\n"); 00508 00509 uint8_t type = matchingServiceUUID.shortOrLong(); 00510 00511 if(type == UUID::UUID_TYPE_SHORT) { 00512 STORE_LE_16(short_uuid, matchingServiceUUID.getShortUUID()); 00513 #ifdef DEBUG 00514 PRINTF("BlueNRGGattConnectionClient launchServiceDiscovery short_uuid=0x"); 00515 for(j = 0; j < 2; j++) { 00516 PRINTF("%02X", short_uuid[j]); 00517 } 00518 PRINTF("\n\r"); 00519 #endif 00520 00521 uuid_type = UUID_TYPE_16; 00522 uuid = short_uuid; 00523 00524 } else if(type==UUID::UUID_TYPE_LONG) { 00525 00526 uuid_type = UUID_TYPE_128; 00527 uuid = (unsigned char*)matchingServiceUUID.getBaseUUID(); 00528 00529 #ifdef DEBUG 00530 PRINTF("BlueNRGGattConnectionClient launchServiceDiscovery base_uuid=0x"); 00531 for(j = 0; j < 16; j++) { 00532 PRINTF("%02X", uuid[j]); 00533 } 00534 PRINTF("\n\r"); 00535 #endif 00536 } 00537 00538 // search for specific service by UUID 00539 ret = aci_gatt_disc_prim_service_by_uuid((uint16_t)_connectionHandle, uuid_type, uuid); 00540 } 00541 00542 if(ret == BLE_STATUS_SUCCESS) { 00543 _currentState = GATT_SERVICE_DISCOVERY; 00544 } 00545 00546 PRINTF("BlueNRGGattConnectionClient launchServiceDiscovery ret=%d\n\r", ret); 00547 00548 return BLE_ERROR_NONE; 00549 } 00550 00551 ble_error_t BlueNRGGattConnectionClient::discoverServices(ServiceDiscovery::ServiceCallback_t callback, 00552 const UUID &matchingServiceUUID) 00553 { 00554 /* avoid compiler warnings about unused variables */ 00555 (void)callback; 00556 (void)matchingServiceUUID; 00557 00558 return BLE_ERROR_NOT_IMPLEMENTED; 00559 } 00560 00561 ble_error_t BlueNRGGattConnectionClient::discoverServices(ServiceDiscovery::ServiceCallback_t callback, 00562 GattAttribute::Handle_t startHandle, 00563 GattAttribute::Handle_t endHandle) 00564 { 00565 /* avoid compiler warnings about unused variables */ 00566 (void)callback; 00567 (void)startHandle; 00568 (void)endHandle; 00569 00570 return BLE_ERROR_NOT_IMPLEMENTED; 00571 } 00572 00573 bool BlueNRGGattConnectionClient::isServiceDiscoveryActive(void) const 00574 { 00575 if(_currentState == GATT_SERVICE_DISCOVERY) { 00576 return true; 00577 } 00578 00579 return false; 00580 } 00581 00582 void BlueNRGGattConnectionClient::terminateServiceDiscovery(void) 00583 { 00584 _currentState = GATT_IDLE;//GATT_DISCOVERY_TERMINATED; 00585 00586 if (terminationCallback) { 00587 terminationCallback(_connectionHandle); 00588 } 00589 } 00590 00591 void BlueNRGGattConnectionClient::charReadCB(uint8_t event_data_length, uint8_t* attribute_value) 00592 { 00593 // copy the data read, they will be forwarded to the user once the procedure 00594 // has completed 00595 readCBParams.connHandle = _connectionHandle; 00596 readCBParams.offset = 0; 00597 readCBParams.len = event_data_length; 00598 readCBParams.data = static_cast<uint8_t*>(malloc(event_data_length)); 00599 memcpy((void*)(readCBParams.data), attribute_value, event_data_length); 00600 } 00601 00602 ble_error_t BlueNRGGattConnectionClient::read(GattAttribute::Handle_t attributeHandle, uint16_t offset) const 00603 { 00604 /* avoid compiler warnings about unused variables */ 00605 (void)offset; 00606 00607 tBleStatus ret; 00608 00609 BlueNRGGattConnectionClient *gattc = const_cast<BlueNRGGattConnectionClient*>(this); 00610 00611 // Save the attribute_handle not provided by evt_att_read_resp 00612 gattc->readCBParams.handle = attributeHandle; 00613 00614 ret = aci_gatt_read_charac_val(_connectionHandle, attributeHandle); 00615 00616 if(ret == BLE_STATUS_SUCCESS) { 00617 gattc->_currentState = GATT_READ_CHAR; 00618 return BLE_ERROR_NONE; 00619 } 00620 switch (ret) { 00621 case ERR_CONTROLLER_BUSY: 00622 return BLE_STACK_BUSY; 00623 default: 00624 return BLE_ERROR_INVALID_STATE; 00625 } 00626 } 00627 00628 void BlueNRGGattConnectionClient::charWritePrepareCB(uint8_t event_data_length, 00629 uint16_t attribute_handle, 00630 uint16_t offset, 00631 uint8_t *part_attr_value) 00632 { 00633 // Update the write response params 00634 writeCBParams.handle = attribute_handle; 00635 writeCBParams.offset = offset; 00636 writeCBParams.len = event_data_length-4; //(?) 00637 writeCBParams.data = part_attr_value; 00638 00639 BlueNRGGattClient::getInstance().processWriteResponse(&writeCBParams); 00640 } 00641 00642 void BlueNRGGattConnectionClient::charWriteExecCB(uint8_t event_data_length) 00643 { 00644 /* avoid compiler warnings about unused variables */ 00645 (void)event_data_length; 00646 00647 writeCBParams.connHandle = _connectionHandle; 00648 00649 BlueNRGGattClient::getInstance().processWriteResponse(&writeCBParams); 00650 } 00651 00652 ble_error_t BlueNRGGattConnectionClient::write(GattClient::WriteOp_t cmd, 00653 GattAttribute::Handle_t attributeHandle, 00654 size_t length, 00655 const uint8_t *value) const 00656 { 00657 /* avoid compiler warnings about unused variables */ 00658 (void)cmd; 00659 uint8_t flag=0; //1 if charHandle found, or 0 00660 tBleStatus ret; 00661 00662 BlueNRGGattConnectionClient *gattc = const_cast<BlueNRGGattConnectionClient*>(this); 00663 00664 // We save the write response params (used by the callback) because 00665 // when the aci_gatt_write_charac_value() is used the only event received is the EVT_BLUE_GATT_PROCEDURE_COMPLETE 00666 gattc->writeCBParams.connHandle = _connectionHandle; 00667 gattc->writeCBParams.writeOp = GattWriteCallbackParams::OP_WRITE_CMD; 00668 gattc->writeCBParams.handle = attributeHandle; 00669 gattc->writeCBParams.offset = 0; 00670 gattc->writeCBParams.len = length; 00671 gattc->writeCBParams.data = value; 00672 00673 00674 00675 00676 //------------------------------------------------------------------------------ 00677 //Edited 00678 00679 00680 for (unsigned i=0; i<BLE_TOTAL_DISCOVERED_CHARS; i++){ 00681 if (attributeHandle == discoveredChar[i].getDeclHandle()){ 00682 flag = 1; 00683 break; 00684 } 00685 //else flag = 0 00686 } 00687 00688 00689 00690 00691 //if flag = 1 write characteristic 00692 if (flag == 1){ 00693 if (cmd == GattClient::GATT_OP_WRITE_REQ){ 00694 //with response (cmd = GattClient::GATT_OP_WRITE_REQ) 00695 ret = aci_gatt_write_charac_value(_connectionHandle, attributeHandle, length, const_cast<uint8_t *>(value)); 00696 00697 }else { 00698 //without response (cmd = GattClient::GATT_OP_WRITE_CMD) 00699 ret = aci_gatt_write_without_response(_connectionHandle, attributeHandle, length, const_cast<uint8_t *>(value)); 00700 } 00701 00702 //if flag = 0 write descriptor 00703 }else { 00704 00705 if (cmd == GattClient::GATT_OP_WRITE_REQ){ 00706 //with response (cmd = GattClient::GATT_OP_WRITE_REQ) 00707 ret = aci_gatt_write_charac_descriptor(_connectionHandle, attributeHandle, length, const_cast<uint8_t *>(value)); 00708 00709 }else { 00710 //without response (cmd = GattClient::GATT_OP_WRITE_CMD) 00711 ret = aci_gatt_write_without_response(_connectionHandle, attributeHandle, length, const_cast<uint8_t *>(value)); 00712 } 00713 } 00714 00715 //------------------------------------------------------------------------------ 00716 00717 00718 00719 00720 00721 00722 if (ret == BLE_STATUS_SUCCESS) { 00723 gattc->_currentState = GATT_WRITE_CHAR; 00724 return BLE_ERROR_NONE; 00725 } 00726 switch (ret) { 00727 case ERR_CONTROLLER_BUSY: 00728 return BLE_STACK_BUSY; 00729 default: 00730 return BLE_ERROR_INVALID_STATE; 00731 } 00732 00733 } 00734 00735 void BlueNRGGattConnectionClient::discAllCharacDescCB(uint8_t event_data_length, 00736 uint8_t format, 00737 uint8_t *handle_uuid_pair) { 00738 GattAttribute::Handle_t attHandle; 00739 UUID uuid; 00740 uint8_t i, numCharacDesc, offset, handle_uuid_length; 00741 00742 handle_uuid_length = 4; //Handle + UUID_16 00743 if (format == 2) 00744 handle_uuid_length = 18; //Handle + UUID_128 00745 00746 numCharacDesc = (event_data_length - 1) / handle_uuid_length; 00747 00748 offset = 0; 00749 00750 PRINTF("\r\ncharacteristic descriptor discovered: data length %u, format %u\r\n", 00751 event_data_length, format); 00752 00753 00754 for (i=0; i<numCharacDesc; i++) { 00755 memcpy(&attHandle, handle_uuid_pair + offset, sizeof(attHandle)); 00756 00757 // UUID Type 00758 if (handle_uuid_length == 4) { 00759 00760 PRINTF("UUID_TYPE_16\n\r"); 00761 uuid = handle_uuid_pair[offset+3]<<8|handle_uuid_pair[offset+2]; 00762 PRINTF("D UUID-%X attHandle=%u\r\n", uuid.getShortUUID(), attHandle); 00763 00764 } else { 00765 00766 PRINTF("UUID_TYPE_128\n\r"); 00767 uuid.setupLong(handle_uuid_pair+offset+2, UUID::LSB); 00768 #ifdef DEBUG 00769 PRINTF("D UUID-"); 00770 const uint8_t *longUUIDBytes = uuid.getBaseUUID(); 00771 for (unsigned j = 0; j < UUID::LENGTH_OF_LONG_UUID; j++) { 00772 PRINTF("%02x", longUUIDBytes[j]); 00773 } 00774 #endif 00775 } 00776 00777 if(charDescDiscoveryCallback != NULL) { 00778 CharacteristicDescriptorDiscovery::DiscoveryCallbackParams_t params = { 00779 _characteristic, 00780 DiscoveredCharacteristicDescriptor( 00781 _characteristic.getGattClient(), 00782 _connectionHandle, 00783 attHandle, 00784 uuid 00785 ) 00786 }; 00787 charDescDiscoveryCallback(¶ms); 00788 } 00789 00790 _numCharDesc++; 00791 00792 offset += handle_uuid_length; 00793 } 00794 } 00795 00796 ble_error_t BlueNRGGattConnectionClient::discoverCharacteristicDescriptors( 00797 const DiscoveredCharacteristic& characteristic, 00798 const CharacteristicDescriptorDiscovery::DiscoveryCallback_t& discoveryCallback, 00799 const CharacteristicDescriptorDiscovery::TerminationCallback_t& terminationCallback) { 00800 00801 tBleStatus ret; 00802 00803 if(_currentState != GATT_IDLE) { 00804 return BLE_ERROR_OPERATION_NOT_PERMITTED; 00805 } 00806 00807 charDescDiscoveryCallback = discoveryCallback; 00808 charDescTerminationCallback = terminationCallback; 00809 00810 GattAttribute::Handle_t valueHandle = characteristic.getValueHandle(); 00811 GattAttribute::Handle_t lastHandle = characteristic.getLastHandle(); 00812 00813 PRINTF("Starting aci_gatt_disc_all_charac_descriptors... [%u : %u]\n\r", valueHandle, lastHandle); 00814 ret = aci_gatt_disc_all_charac_descriptors(_connectionHandle, valueHandle, lastHandle); 00815 00816 if (ret == BLE_STATUS_SUCCESS) { 00817 _currentState = GATT_CHAR_DESC_DISCOVERY; 00818 _characteristic = characteristic; 00819 return BLE_ERROR_NONE; 00820 } 00821 switch (ret) { 00822 case BLE_STATUS_INVALID_PARAMS: 00823 return BLE_ERROR_INVALID_PARAM; 00824 default: 00825 return BLE_ERROR_OPERATION_NOT_PERMITTED; 00826 } 00827 } 00828 00829 /**************************************************************************/ 00830 /*! 00831 @brief Clear BlueNRGGattServer's state. 00832 00833 @returns ble_error_t 00834 00835 @retval BLE_ERROR_NONE 00836 Everything executed properly 00837 */ 00838 /**************************************************************************/ 00839 ble_error_t BlueNRGGattConnectionClient::reset(void) { 00840 PRINTF("BlueNRGGattConnectionClient::reset\n"); 00841 00842 /* Clear all state, including private members */ 00843 00844 _currentState = GATT_IDLE; 00845 _matchingServiceUUID = BLE_UUID_UNKNOWN; 00846 _matchingCharacteristicUUIDIn = BLE_UUID_UNKNOWN; 00847 00848 _numServices = 0; 00849 _servIndex = 0; 00850 _numChars = 0; 00851 _numCharDesc = 0; 00852 00853 /* Clear class members */ 00854 memset(discoveredService, 0, sizeof(discoveredService)); 00855 memset(discoveredChar, 0, sizeof(discoveredChar)); 00856 00857 // free response if allocated 00858 if(readCBParams.data) { 00859 free((void*)(readCBParams.data)); 00860 } 00861 00862 return BLE_ERROR_NONE; 00863 }
Generated on Tue Jul 12 2022 21:44:00 by
1.7.2