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