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