mamont mamont
/
test_ble
nrf52-dk
shields/TARGET_ST_BLUENRG/source/BlueNRGGattConnectionClient.cpp
- Committer:
- mamont090671
- Date:
- 2020-06-05
- Revision:
- 0:70ce6da7a141
File content as of revision 0:70ce6da7a141:
/* mbed Microcontroller Library * Copyright (c) 2006-2013 ARM Limited * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ /** ****************************************************************************** * @file BlueNRGGattServer.cpp * @author STMicroelectronics * @brief Implementation of BlueNRG BLE_API GattServer Class ****************************************************************************** * @copy * * THE PRESENT FIRMWARE WHICH IS FOR GUIDANCE ONLY AIMS AT PROVIDING CUSTOMERS * WITH CODING INFORMATION REGARDING THEIR PRODUCTS IN ORDER FOR THEM TO SAVE * TIME. AS A RESULT, STMICROELECTRONICS SHALL NOT BE HELD LIABLE FOR ANY * DIRECT, INDIRECT OR CONSEQUENTIAL DAMAGES WITH RESPECT TO ANY CLAIMS ARISING * FROM THE CONTENT OF SUCH FIRMWARE AND/OR THE USE MADE BY CUSTOMERS OF THE * CODING INFORMATION CONTAINED HEREIN IN CONNECTION WITH THEIR PRODUCTS. * * <h2><center>© COPYRIGHT 2013 STMicroelectronics</center></h2> */ /** @defgroup BlueNRGGattConnectionClient * @brief BlueNRG GattConnectionClient Adaptation * @{ */ #include "BlueNRGGattConnectionClient.h" #ifdef YOTTA_CFG_MBED_OS #include "mbed-drivers/mbed.h" #else #include "mbed.h" #endif #include "BlueNRGGap.h" #include "BlueNRGGattClient.h" #include "ble_utils.h" #include "ble_debug.h" // #define PRINTF printf static uint8_t props_mask[] = { 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, 0x40, 0x80 }; void BlueNRGGattConnectionClient::gattProcedureCompleteCB(uint8_t error_code) { if(error_code != BLE_STATUS_SUCCESS) { _currentState = GATT_IDLE; return; } // Service Discovery complete /* if(_currentState != GATT_IDLE && _currentState != GATT_DISCOVERY_TERMINATED && _currentState != GATT_WRITE_CHAR && _currentState != GATT_READ_CHAR) { */ if(_currentState == GATT_SERVICE_DISCOVERY) { findServiceChars(); return; } if(_currentState == GATT_CHAR_DESC_DISCOVERY) { _currentState = GATT_IDLE; if(charDescTerminationCallback != NULL) { CharacteristicDescriptorDiscovery::TerminationCallbackParams_t params = { _characteristic, BLE_ERROR_NONE }; charDescTerminationCallback(¶ms); } return; } // Read complete if(_currentState == GATT_READ_CHAR) { _currentState = GATT_IDLE; BlueNRGGattClient::getInstance().processReadResponse(&readCBParams); free((void*)(readCBParams.data)); readCBParams.data = NULL; return; } // Write complete if(_currentState == GATT_WRITE_CHAR) { _currentState = GATT_IDLE; BlueNRGGattClient::getInstance().processWriteResponse(&writeCBParams); return; } } void BlueNRGGattConnectionClient::primaryServicesCB(uint8_t event_data_length, uint8_t attribute_data_length, uint8_t *attribute_data_list) { GattAttribute::Handle_t startHandle, endHandle; UUID uuid; uint8_t i, offset, numAttr; numAttr = (event_data_length - 1) / attribute_data_length; offset = 0; for (i=0; i<numAttr; i++) { startHandle = attribute_data_list[offset]; endHandle = attribute_data_list[offset+2]; // UUID Type if (attribute_data_length == 6) { PRINTF("UUID_TYPE_16\n\r"); uuid = attribute_data_list[offset+5]<<8|attribute_data_list[offset+4]; PRINTF("S UUID-%X attrs[%u %u]\r\n", uuid.getShortUUID(), startHandle, endHandle); } else { PRINTF("UUID_TYPE_128\n\r"); uuid.setupLong(attribute_data_list+offset+4, UUID::LSB); #ifdef DEBUG PRINTF("S UUID-"); const uint8_t *longUUIDBytes = uuid.getBaseUUID(); for (unsigned j = 0; j < UUID::LENGTH_OF_LONG_UUID; j++) { PRINTF("%02x", longUUIDBytes[j]); } #endif PRINTF(" attrs[%u %u]\r\n", startHandle, endHandle); } PRINTF("Setup serviceIndex = %d\n\r", _numServices); discoveredService[_numServices].setup(uuid, startHandle, endHandle); _numServices++; offset += attribute_data_length; } PRINTF("!!!Service Discovery complete (numAttr=%u)!!!\n\r", numAttr); } void BlueNRGGattConnectionClient::primaryServiceCB(uint8_t event_data_length, uint8_t *handles_info_list) { GattAttribute::Handle_t startHandle, endHandle; UUID uuid; uint8_t i, offset, numHandlePairs; numHandlePairs = (event_data_length - 1) / 2; offset = 0; for (i=0; i<numHandlePairs; i++) { startHandle = handles_info_list[offset]; endHandle = handles_info_list[offset+2]; PRINTF("primaryServiceCB attrs[%u %u]\r\n", startHandle, endHandle); if (_matchingServiceUUID.shortOrLong() == UUID::UUID_TYPE_SHORT) { PRINTF("S UUID-%x attrs[%u %u]\r\n", _matchingServiceUUID.getShortUUID(), startHandle, endHandle); uuid = _matchingServiceUUID.getShortUUID(); } else { #ifdef DEBUG PRINTF("S UUID-"); const uint8_t *longUUIDBytes = _matchingServiceUUID.getBaseUUID(); for (unsigned i = 0; i < UUID::LENGTH_OF_LONG_UUID; i++) { PRINTF("%02x", longUUIDBytes[i]); } #endif PRINTF(" attrs[%u %u]\r\n", startHandle, endHandle); uuid.setupLong(_matchingServiceUUID.getBaseUUID(), UUID::MSB); } discoveredService[i].setup(uuid, startHandle, endHandle); _numServices++; offset += 4; } } void BlueNRGGattConnectionClient::serviceCharsCB(uint8_t event_data_length, uint8_t handle_value_pair_length, uint8_t *handle_value_pair) { // Charac Handle (2), Charac Properties(1), Charac Value Handle(2), Charac UUID(2/16) GattAttribute::Handle_t declHandle, valueHandle, lastHandle; UUID uuid; uint8_t i, numChar, offset; numChar = (event_data_length - 1) / handle_value_pair_length; PRINTF("event_data_length=%d handle_value_pair_length=%d numChar=%d\n\r", event_data_length, handle_value_pair_length, numChar); offset = 0; for (i=0; i<numChar; i++) { // UUID Type if (handle_value_pair_length == 7) { PRINTF("Char UUID_TYPE_16\n\r"); uuid = handle_value_pair[offset+6]<<8|handle_value_pair[offset+5]; PRINTF("C UUID-%X\r\n", uuid.getShortUUID()); } else { PRINTF("Char UUID_TYPE_128\n\r"); uuid.setupLong(handle_value_pair+offset+5, UUID::LSB); #ifdef DEBUG PRINTF("C UUID-"); const uint8_t *longUUIDBytes = uuid.getBaseUUID(); for (unsigned i = 0; i < UUID::LENGTH_OF_LONG_UUID; i++) { PRINTF("%02X", longUUIDBytes[i]); } PRINTF("\r\n"); #endif } // Properties DiscoveredCharacteristic::Properties_t p; p._broadcast = (props_mask[0] & handle_value_pair[offset+2]); p._read = (props_mask[1] & handle_value_pair[offset+2])>>1; p._writeWoResp = (props_mask[2] & handle_value_pair[offset+2])>>2; p._write = (props_mask[3] & handle_value_pair[offset+2])>>3; p._notify = (props_mask[4] & handle_value_pair[offset+2])>>4; p._indicate = (props_mask[5] & handle_value_pair[offset+2])>>5; p._authSignedWrite = (props_mask[6] & handle_value_pair[offset+2])>>6; PRINTF("p._broadcast=%d\n\r", p._broadcast); PRINTF("p._read=%d\n\r", p._read); PRINTF("p._writeWoResp=%d\n\r", p._writeWoResp); PRINTF("p._write=%d\n\r", p._write); PRINTF("p._notify=%d\n\r", p._notify); PRINTF("p._indicate=%d\n\r", p._indicate); PRINTF("p._authSignedWrite=%d\n\r", p._authSignedWrite); /* uint8_t props = handle_value_pair[offset+2]; PRINTF("CHAR PROPS: %d\n\r", props); */ // Handles declHandle = handle_value_pair[offset]; valueHandle = handle_value_pair[offset+3]; lastHandle = valueHandle+1; PRINTF("declHandle: %u valueHandle=%u lastHandle=%u\n\r", declHandle, valueHandle, lastHandle); discoveredChar[_numChars].setup(_gattClient, _connectionHandle, uuid, p, declHandle, valueHandle, lastHandle); if (_numChars != 0) { discoveredChar[_numChars - 1].setLastHandle(declHandle - 1); if(characteristicDiscoveryCallback) { characteristicDiscoveryCallback(&discoveredChar[_numChars - 1]); } } _numChars++; offset += handle_value_pair_length; } } void BlueNRGGattConnectionClient::serviceCharByUUIDCB(uint8_t event_data_length, uint16_t attr_handle, uint8_t *attr_value) { // Charac Properties(1), Charac Value Handle(2), Charac UUID(2/16) GattAttribute::Handle_t declHandle, valueHandle, lastHandle; UUID uuid; PRINTF("serviceCharByUUIDCB\n\r"); // UUID Type if (event_data_length == 7) { PRINTF("Char UUID_TYPE_16\n\r"); uuid = attr_value[4]<<8|attr_value[3]; PRINTF("C UUID-%X\r\n", uuid.getShortUUID()); } else { PRINTF("Char UUID_TYPE_128\n\r"); uuid.setupLong(attr_value+3, UUID::LSB); #ifdef DEBUG PRINTF("C UUID-"); const uint8_t *longUUIDBytes = uuid.getBaseUUID(); for (unsigned i = 0; i < UUID::LENGTH_OF_LONG_UUID; i++) { PRINTF("%02X", longUUIDBytes[i]); } PRINTF("\r\n"); #endif } // Properties DiscoveredCharacteristic::Properties_t p; p._broadcast = (props_mask[0] & attr_value[0]); p._read = (props_mask[1] & attr_value[0])>>1; p._writeWoResp = (props_mask[2] & attr_value[0])>>2; p._write = (props_mask[3] & attr_value[0])>>3; p._notify = (props_mask[4] & attr_value[0])>>4; p._indicate = (props_mask[5] & attr_value[0])>>5; p._authSignedWrite = (props_mask[6] & attr_value[0])>>6; PRINTF("p._broadcast=%d\n\r", p._broadcast); PRINTF("p._read=%d\n\r", p._read); PRINTF("p._writeWoResp=%d\n\r", p._writeWoResp); PRINTF("p._write=%d\n\r", p._write); PRINTF("p._notify=%d\n\r", p._notify); PRINTF("p._indicate=%d\n\r", p._indicate); PRINTF("p._authSignedWrite=%d\n\r", p._authSignedWrite); /* uint8_t props = attr_value[0]; PRINTF("CHAR PROPS: %d\n\r", props); */ // Handles declHandle = attr_handle; valueHandle = attr_value[1]; lastHandle = valueHandle+1; discoveredChar[_numChars].setup(_gattClient, _connectionHandle, uuid, p, declHandle, valueHandle, lastHandle); // update the last handle and call the characteristic discovery callback for previous char if (_numChars != 0) { discoveredChar[_numChars - 1].setLastHandle(declHandle - 1); if(characteristicDiscoveryCallback) { characteristicDiscoveryCallback(&discoveredChar[_numChars - 1]); } } _numChars++; } ble_error_t BlueNRGGattConnectionClient::findServiceChars(void) { PRINTF("findServiceChars\n\r"); tBleStatus ret; uint8_t uuid_type = UUID_TYPE_16; uint8_t short_uuid[2]; uint8_t *uuid = NULL; DiscoveredService *service; // complete the discovery of the last characteristic of the previous service. // Its last handle wasn't known before this point // update the handle and call the characteristic discovery callback. if (_servIndex != 0 && _numChars != 0) { discoveredChar[_numChars - 1].setLastHandle(discoveredService[_servIndex - 1].getEndHandle()); if(characteristicDiscoveryCallback) { characteristicDiscoveryCallback(&discoveredChar[_numChars - 1]); } } _numChars = 0; // We finished chars discovery for all services if(_servIndex >= _numServices) { PRINTF("!!!We finished chars discovery for all services!!!\n\r"); //_currentState = GATT_CHARS_DISCOVERY_COMPLETE; terminateServiceDiscovery(); return BLE_ERROR_NONE; } service = &discoveredService[_servIndex]; /* if (service->getUUID().shortOrLong() == UUID::UUID_TYPE_SHORT) { PRINTF("S UUID-%X\r\n", service->getUUID().getShortUUID()); } else { PRINTF("S UUID-"); const uint8_t *longUUIDBytes = service->getUUID().getBaseUUID(); for (unsigned i = 0; i < UUID::LENGTH_OF_LONG_UUID; i++) { PRINTF("%02X", longUUIDBytes[i]); } PRINTF("\r\n"); } */ if(serviceDiscoveryCallback) { serviceDiscoveryCallback(service); } PRINTF("findServiceChars (_servIndex=%d)\n\r", _servIndex); //ret = aci_gatt_disc_all_charac_of_serv(connectionHandle, service->getStartHandle(), service->getEndHandle()); if(_matchingCharacteristicUUIDIn == BLE_UUID_UNKNOWN) { PRINTF("findServiceChars (BLE_UUID_UNKNOWN)\n\r"); ret = aci_gatt_disc_all_charac_of_serv(_connectionHandle, service->getStartHandle(), service->getEndHandle()); } else { uint8_t type = _matchingCharacteristicUUIDIn.shortOrLong(); if(type == UUID::UUID_TYPE_SHORT) { STORE_LE_16(short_uuid, _matchingCharacteristicUUIDIn.getShortUUID()); uuid_type = UUID_TYPE_16; uuid = short_uuid; #ifdef DEBUG PRINTF("findServiceChars C UUID-"); for(unsigned i = 0; i < 2; i++) { PRINTF("%02X", short_uuid[i]); } PRINTF("\n\r"); #endif } else if(type==UUID::UUID_TYPE_LONG) { uuid_type = UUID_TYPE_128; uuid = (unsigned char*)_matchingCharacteristicUUIDIn.getBaseUUID(); #ifdef DEBUG PRINTF("(findServiceChars) C UUID-"); for (unsigned i = 0; i < UUID::LENGTH_OF_LONG_UUID; i++) { PRINTF("%02X", uuid[i]); } PRINTF("\r\n"); #endif } ret = aci_gatt_disc_charac_by_uuid(_connectionHandle, service->getStartHandle(), service->getEndHandle(), uuid_type, uuid); } if(ret == BLE_STATUS_SUCCESS) { _servIndex++; } PRINTF("findServiceChars ret=%d\n\r", ret); return BLE_ERROR_NONE; } ble_error_t BlueNRGGattConnectionClient::launchServiceDiscovery(ServiceDiscovery::ServiceCallback_t sc, ServiceDiscovery::CharacteristicCallback_t cc, const UUID &matchingServiceUUID, const UUID &matchingCharacteristicUUIDIn) { PRINTF("BlueNRGGattConnectionClient launchServiceDiscovery\n\r"); tBleStatus ret; uint8_t uuid_type = UUID_TYPE_16; uint8_t short_uuid[2]; uint8_t *uuid = NULL; unsigned j; if(isServiceDiscoveryActive()) { return BLE_ERROR_OPERATION_NOT_PERMITTED; } if(!sc && !cc) { // nothing to do PRINTF("BlueNRGGattConnectionClient launchServiceDiscovery: nothing to do\n\r"); return BLE_ERROR_NONE; } serviceDiscoveryCallback = sc; characteristicDiscoveryCallback = cc; _matchingServiceUUID = matchingServiceUUID; _matchingCharacteristicUUIDIn = matchingCharacteristicUUIDIn; //reset services _numServices = 0; _numChars = 0; _servIndex = 0; for(j = 0; j < BLE_TOTAL_DISCOVERED_SERVICES; j++) { discoveredService[j].setup(BLE_UUID_UNKNOWN, GattAttribute::INVALID_HANDLE, GattAttribute::INVALID_HANDLE); } if(matchingServiceUUID == BLE_UUID_UNKNOWN) { // Wildcard: search for all services PRINTF("Wildcard: search for all services\r\n"); ret = aci_gatt_disc_all_prim_services((uint16_t)_connectionHandle); } else { PRINTF("search for specific services\r\n"); uint8_t type = matchingServiceUUID.shortOrLong(); if(type == UUID::UUID_TYPE_SHORT) { STORE_LE_16(short_uuid, matchingServiceUUID.getShortUUID()); #ifdef DEBUG PRINTF("BlueNRGGattConnectionClient launchServiceDiscovery short_uuid=0x"); for(j = 0; j < 2; j++) { PRINTF("%02X", short_uuid[j]); } PRINTF("\n\r"); #endif uuid_type = UUID_TYPE_16; uuid = short_uuid; } else if(type==UUID::UUID_TYPE_LONG) { uuid_type = UUID_TYPE_128; uuid = (unsigned char*)matchingServiceUUID.getBaseUUID(); #ifdef DEBUG PRINTF("BlueNRGGattConnectionClient launchServiceDiscovery base_uuid=0x"); for(j = 0; j < 16; j++) { PRINTF("%02X", uuid[j]); } PRINTF("\n\r"); #endif } // search for specific service by UUID ret = aci_gatt_disc_prim_service_by_uuid((uint16_t)_connectionHandle, uuid_type, uuid); } if(ret == BLE_STATUS_SUCCESS) { _currentState = GATT_SERVICE_DISCOVERY; } PRINTF("BlueNRGGattConnectionClient launchServiceDiscovery ret=%d\n\r", ret); return BLE_ERROR_NONE; } ble_error_t BlueNRGGattConnectionClient::discoverServices(ServiceDiscovery::ServiceCallback_t callback, const UUID &matchingServiceUUID) { /* avoid compiler warnings about unused variables */ (void)callback; (void)matchingServiceUUID; return BLE_ERROR_NOT_IMPLEMENTED; } ble_error_t BlueNRGGattConnectionClient::discoverServices(ServiceDiscovery::ServiceCallback_t callback, GattAttribute::Handle_t startHandle, GattAttribute::Handle_t endHandle) { /* avoid compiler warnings about unused variables */ (void)callback; (void)startHandle; (void)endHandle; return BLE_ERROR_NOT_IMPLEMENTED; } bool BlueNRGGattConnectionClient::isServiceDiscoveryActive(void) const { if(_currentState == GATT_SERVICE_DISCOVERY) { return true; } return false; } void BlueNRGGattConnectionClient::terminateServiceDiscovery(void) { _currentState = GATT_IDLE;//GATT_DISCOVERY_TERMINATED; if (terminationCallback) { terminationCallback(_connectionHandle); } } void BlueNRGGattConnectionClient::charReadCB(uint8_t event_data_length, uint8_t* attribute_value) { // copy the data read, they will be forwarded to the user once the procedure // has completed readCBParams.connHandle = _connectionHandle; readCBParams.offset = 0; readCBParams.len = event_data_length; readCBParams.data = static_cast<uint8_t*>(malloc(event_data_length)); memcpy((void*)(readCBParams.data), attribute_value, event_data_length); } ble_error_t BlueNRGGattConnectionClient::read(GattAttribute::Handle_t attributeHandle, uint16_t offset) const { /* avoid compiler warnings about unused variables */ (void)offset; tBleStatus ret; BlueNRGGattConnectionClient *gattc = const_cast<BlueNRGGattConnectionClient*>(this); // Save the attribute_handle not provided by evt_att_read_resp gattc->readCBParams.handle = attributeHandle; ret = aci_gatt_read_charac_val(_connectionHandle, attributeHandle); if(ret == BLE_STATUS_SUCCESS) { gattc->_currentState = GATT_READ_CHAR; return BLE_ERROR_NONE; } switch (ret) { case ERR_CONTROLLER_BUSY: return BLE_STACK_BUSY; default: return BLE_ERROR_INVALID_STATE; } } void BlueNRGGattConnectionClient::charWritePrepareCB(uint8_t event_data_length, uint16_t attribute_handle, uint16_t offset, uint8_t *part_attr_value) { // Update the write response params writeCBParams.handle = attribute_handle; writeCBParams.offset = offset; writeCBParams.len = event_data_length-4; //(?) writeCBParams.data = part_attr_value; BlueNRGGattClient::getInstance().processWriteResponse(&writeCBParams); } void BlueNRGGattConnectionClient::charWriteExecCB(uint8_t event_data_length) { /* avoid compiler warnings about unused variables */ (void)event_data_length; writeCBParams.connHandle = _connectionHandle; BlueNRGGattClient::getInstance().processWriteResponse(&writeCBParams); } ble_error_t BlueNRGGattConnectionClient::write(GattClient::WriteOp_t cmd, GattAttribute::Handle_t attributeHandle, size_t length, const uint8_t *value) const { /* avoid compiler warnings about unused variables */ (void)cmd; tBleStatus ret; BlueNRGGattConnectionClient *gattc = const_cast<BlueNRGGattConnectionClient*>(this); // We save the write response params (used by the callback) because // when the aci_gatt_write_charac_value() is used the only event received is the EVT_BLUE_GATT_PROCEDURE_COMPLETE gattc->writeCBParams.connHandle = _connectionHandle; gattc->writeCBParams.writeOp = GattWriteCallbackParams::OP_WRITE_CMD; gattc->writeCBParams.handle = attributeHandle; gattc->writeCBParams.offset = 0; gattc->writeCBParams.len = length; gattc->writeCBParams.data = value; ret = aci_gatt_write_charac_value(_connectionHandle, attributeHandle, length, const_cast<uint8_t *>(value)); if (ret == BLE_STATUS_SUCCESS) { gattc->_currentState = GATT_WRITE_CHAR; return BLE_ERROR_NONE; } switch (ret) { case ERR_CONTROLLER_BUSY: return BLE_STACK_BUSY; default: return BLE_ERROR_INVALID_STATE; } } void BlueNRGGattConnectionClient::discAllCharacDescCB(uint8_t event_data_length, uint8_t format, uint8_t *handle_uuid_pair) { GattAttribute::Handle_t attHandle; UUID uuid; uint8_t i, numCharacDesc, offset, handle_uuid_length; handle_uuid_length = 4; //Handle + UUID_16 if (format == 2) handle_uuid_length = 18; //Handle + UUID_128 numCharacDesc = (event_data_length - 1) / handle_uuid_length; offset = 0; PRINTF("\r\ncharacteristic descriptor discovered: data length %u, format %u\r\n", event_data_length, format); for (i=0; i<numCharacDesc; i++) { memcpy(&attHandle, handle_uuid_pair + offset, sizeof(attHandle)); // UUID Type if (handle_uuid_length == 4) { PRINTF("UUID_TYPE_16\n\r"); uuid = handle_uuid_pair[offset+3]<<8|handle_uuid_pair[offset+2]; PRINTF("D UUID-%X attHandle=%u\r\n", uuid.getShortUUID(), attHandle); } else { PRINTF("UUID_TYPE_128\n\r"); uuid.setupLong(handle_uuid_pair+offset+2, UUID::LSB); #ifdef DEBUG PRINTF("D UUID-"); const uint8_t *longUUIDBytes = uuid.getBaseUUID(); for (unsigned j = 0; j < UUID::LENGTH_OF_LONG_UUID; j++) { PRINTF("%02x", longUUIDBytes[j]); } #endif } if(charDescDiscoveryCallback != NULL) { CharacteristicDescriptorDiscovery::DiscoveryCallbackParams_t params = { _characteristic, DiscoveredCharacteristicDescriptor( _characteristic.getGattClient(), _connectionHandle, attHandle, uuid ) }; charDescDiscoveryCallback(¶ms); } _numCharDesc++; offset += handle_uuid_length; } } ble_error_t BlueNRGGattConnectionClient::discoverCharacteristicDescriptors( const DiscoveredCharacteristic& characteristic, const CharacteristicDescriptorDiscovery::DiscoveryCallback_t& discoveryCallback, const CharacteristicDescriptorDiscovery::TerminationCallback_t& terminationCallback) { tBleStatus ret; if(_currentState != GATT_IDLE) { return BLE_ERROR_OPERATION_NOT_PERMITTED; } charDescDiscoveryCallback = discoveryCallback; charDescTerminationCallback = terminationCallback; GattAttribute::Handle_t valueHandle = characteristic.getValueHandle(); GattAttribute::Handle_t lastHandle = characteristic.getLastHandle(); PRINTF("Starting aci_gatt_disc_all_charac_descriptors... [%u : %u]\n\r", valueHandle, lastHandle); ret = aci_gatt_disc_all_charac_descriptors(_connectionHandle, valueHandle, lastHandle); if (ret == BLE_STATUS_SUCCESS) { _currentState = GATT_CHAR_DESC_DISCOVERY; _characteristic = characteristic; return BLE_ERROR_NONE; } switch (ret) { case BLE_STATUS_INVALID_PARAMS: return BLE_ERROR_INVALID_PARAM; default: return BLE_ERROR_OPERATION_NOT_PERMITTED; } } /**************************************************************************/ /*! @brief Clear BlueNRGGattServer's state. @returns ble_error_t @retval BLE_ERROR_NONE Everything executed properly */ /**************************************************************************/ ble_error_t BlueNRGGattConnectionClient::reset(void) { PRINTF("BlueNRGGattConnectionClient::reset\n"); /* Clear all state, including private members */ _currentState = GATT_IDLE; _matchingServiceUUID = BLE_UUID_UNKNOWN; _matchingCharacteristicUUIDIn = BLE_UUID_UNKNOWN; _numServices = 0; _servIndex = 0; _numChars = 0; _numCharDesc = 0; /* Clear class members */ memset(discoveredService, 0, sizeof(discoveredService)); memset(discoveredChar, 0, sizeof(discoveredChar)); // free response if allocated if(readCBParams.data) { free((void*)(readCBParams.data)); } return BLE_ERROR_NONE; }