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