Relaunch discovery operation when gatt event status is

BLE_GATT_STATUS_SUCCESS.
Report error in the Termination callback
This commit is contained in:
Vincent Coubard 2015-11-17 10:24:57 +00:00
parent e15d59a758
commit cdd5b92193
4 changed files with 95 additions and 61 deletions

View file

@ -97,16 +97,24 @@ void bleGattcEventHandler(const ble_evt_t *p_ble_evt)
case BLE_GATTC_EVT_DESC_DISC_RSP: {
uint16_t conn_handle = p_ble_evt->evt.gattc_evt.conn_handle;
uint16_t status = p_ble_evt->evt.gattc_evt.gatt_status;
ble_gattc_evt_desc_disc_rsp_t discovered_descriptors = p_ble_evt->evt.gattc_evt.params.desc_disc_rsp;
if (p_ble_evt->evt.gattc_evt.gatt_status != BLE_GATT_STATUS_SUCCESS) {
characteristicDescriptorDiscoverer.terminate(conn_handle);
return;
switch(status) {
case BLE_GATT_STATUS_SUCCESS:
characteristicDescriptorDiscoverer.process(
conn_handle,
discovered_descriptors
);
break;
case BLE_GATT_STATUS_ATTERR_ATTRIBUTE_NOT_FOUND:
// end of discovery
characteristicDescriptorDiscoverer.terminate(conn_handle, BLE_ERROR_NONE);
break;
default:
characteristicDescriptorDiscoverer.terminate(conn_handle, BLE_ERROR_UNSPECIFIED);
break;
}
characteristicDescriptorDiscoverer.process(
conn_handle,
/* discoveredDescriptors */ p_ble_evt->evt.gattc_evt.params.desc_disc_rsp
);
} break;
}

View file

@ -35,7 +35,8 @@ ble_error_t nRF5xCharacteristicDescriptorDiscoverer::launch(
// check if their is any descriptor to discover
if (descriptorEndHandle < descriptorStartHandle) {
CharacteristicDescriptorDiscovery::TerminationCallbackParams_t termParams = {
characteristic
characteristic,
BLE_ERROR_NONE
};
terminationCallback.call(&termParams);
return BLE_ERROR_NONE;
@ -53,30 +54,13 @@ ble_error_t nRF5xCharacteristicDescriptorDiscoverer::launch(
}
// try to launch the discovery
ble_gattc_handle_range_t discoveryRange = {
descriptorStartHandle,
descriptorEndHandle
};
uint32_t err = sd_ble_gattc_descriptors_discover(characteristic.getConnectionHandle(), &discoveryRange);
switch(err) {
case NRF_SUCCESS:
// commit the new discovery to its slot
*discovery = Discovery(
characteristic,
discoveryCallback,
terminationCallback
);
return BLE_ERROR_NONE;
case BLE_ERROR_INVALID_CONN_HANDLE:
return BLE_ERROR_INVALID_PARAM;
case NRF_ERROR_INVALID_ADDR:
return BLE_ERROR_PARAM_OUT_OF_RANGE;
case NRF_ERROR_BUSY:
return BLE_STACK_BUSY;
default:
return BLE_ERROR_UNSPECIFIED;
ble_error_t err = gattc_descriptors_discover(connHandle, descriptorStartHandle, descriptorEndHandle);
if(!err) {
// commit the new discovery to its slot
*discovery = Discovery(characteristic, discoveryCallback, terminationCallback);
}
return err;
}
bool nRF5xCharacteristicDescriptorDiscoverer::isActive(const DiscoveredCharacteristic& characteristic) const {
@ -88,13 +72,13 @@ void nRF5xCharacteristicDescriptorDiscoverer::requestTerminate(const DiscoveredC
if(discovery) {
discovery->onDiscovery = emptyDiscoveryCallback;
// call terminate anyway
discovery->terminate();
discovery->terminate(BLE_ERROR_NONE);
discovery->onTerminate = emptyTerminationCallback;
}
}
void nRF5xCharacteristicDescriptorDiscoverer::process(uint16_t handle, const ble_gattc_evt_desc_disc_rsp_t& descriptors) {
Discovery* discovery = findRunningDiscovery(handle);
void nRF5xCharacteristicDescriptorDiscoverer::process(uint16_t connectionHandle, const ble_gattc_evt_desc_disc_rsp_t& descriptors) {
Discovery* discovery = findRunningDiscovery(connectionHandle);
if(!discovery) {
error("logic error in nRF5xCharacteristicDescriptorDiscoverer::process !!!");
}
@ -104,14 +88,30 @@ void nRF5xCharacteristicDescriptorDiscoverer::process(uint16_t handle, const ble
descriptors.descs[i].handle, UUID(descriptors.descs[i].uuid.uuid)
);
}
// prepare the next discovery request (if needed)
uint16_t startHandle = descriptors.descs[descriptors.count - 1].handle + 1;
uint16_t endHandle = discovery->characteristic.getLastHandle();
if(startHandle > endHandle ||
(discovery->onDiscovery == emptyDiscoveryCallback && discovery->onTerminate == emptyTerminationCallback)) {
terminate(connectionHandle, BLE_ERROR_NONE);
return;
}
ble_error_t err = gattc_descriptors_discover(connectionHandle, startHandle, endHandle);
if(err) {
terminate(connectionHandle, err);
return;
}
}
void nRF5xCharacteristicDescriptorDiscoverer::terminate(uint16_t handle) {
void nRF5xCharacteristicDescriptorDiscoverer::terminate(uint16_t handle, ble_error_t err) {
Discovery* discovery = findRunningDiscovery(handle);
if(!discovery) {
error("logic error in nRF5xCharacteristicDescriptorDiscoverer::process !!!");
}
discovery->terminate();
discovery->terminate(err);
removeDiscovery(discovery);
}
@ -166,3 +166,26 @@ nRF5xCharacteristicDescriptorDiscoverer::getAvailableDiscoverySlot() {
bool nRF5xCharacteristicDescriptorDiscoverer::isConnectionInUse(uint16_t connHandle) {
return findRunningDiscovery(connHandle) != NULL;
}
ble_error_t nRF5xCharacteristicDescriptorDiscoverer::gattc_descriptors_discover(
uint16_t connection_handle, uint16_t start_handle, uint16_t end_handle) {
ble_gattc_handle_range_t discoveryRange = {
start_handle,
end_handle
};
uint32_t err = sd_ble_gattc_descriptors_discover(connection_handle, &discoveryRange);
switch(err) {
case NRF_SUCCESS:
return BLE_ERROR_NONE;
case BLE_ERROR_INVALID_CONN_HANDLE:
return BLE_ERROR_INVALID_PARAM;
case NRF_ERROR_INVALID_ADDR:
return BLE_ERROR_PARAM_OUT_OF_RANGE;
case NRF_ERROR_BUSY:
return BLE_STACK_BUSY;
default:
return BLE_ERROR_UNSPECIFIED;
}
}

View file

@ -73,7 +73,7 @@ public:
/**
* @brief Called by the nordic stack when the discovery is over.
*/
void terminate(uint16_t handle);
void terminate(uint16_t handle, ble_error_t err);
private:
nRF5xCharacteristicDescriptorDiscoverer(const nRF5xCharacteristicDescriptorDiscoverer&);
@ -105,9 +105,10 @@ private:
onDiscovery.call(&params);
}
void terminate() {
void terminate(ble_error_t err) {
CharacteristicDescriptorDiscovery::TerminationCallbackParams_t params = {
characteristic
characteristic,
err
};
onTerminate.call(&params);
}
@ -125,6 +126,8 @@ private:
void removeDiscovery(Discovery* discovery);
Discovery* getAvailableDiscoverySlot();
bool isConnectionInUse(uint16_t connHandle);
static ble_error_t gattc_descriptors_discover(uint16_t connection_handle, uint16_t start_handle, uint16_t end_handle);
size_t maximumConcurrentConnectionsCount;
Discovery *discoveryRunning;

View file

@ -78,7 +78,6 @@ nRF5xServiceDiscovery::setupDiscoveredServices(const ble_gattc_evt_prim_srvc_dis
void
nRF5xServiceDiscovery::setupDiscoveredCharacteristics(const ble_gattc_evt_char_disc_rsp_t *response)
{
characteristicIndex = 0;
numCharacteristics = response->count;
/* Account for the limitation on the number of discovered characteristics we can handle at a time. */
@ -114,37 +113,38 @@ nRF5xServiceDiscovery::setupDiscoveredCharacteristics(const ble_gattc_evt_char_d
void
nRF5xServiceDiscovery::progressCharacteristicDiscovery(void)
{
/* Iterate through the previously discovered characteristics cached in characteristics[]. */
while ((state == CHARACTERISTIC_DISCOVERY_ACTIVE) && (characteristicIndex < numCharacteristics)) {
for(uint8_t i = 0; i < numCharacteristics; ++i) {
if(state != CHARACTERISTIC_DISCOVERY_ACTIVE) {
return;
}
if ((matchingCharacteristicUUID == UUID::ShortUUIDBytes_t(BLE_UUID_UNKNOWN)) ||
((matchingCharacteristicUUID == characteristics[characteristicIndex].getUUID()) &&
(matchingServiceUUID != UUID::ShortUUIDBytes_t(BLE_UUID_UNKNOWN)))) {
if (characteristicCallback) {
characteristicCallback(&characteristics[characteristicIndex]);
characteristicCallback(&characteristics[i]);
}
}
characteristicIndex++;
}
/* Relaunch discovery of new characteristics beyond the last entry cached in characteristics[]. */
if (state == CHARACTERISTIC_DISCOVERY_ACTIVE) {
/* Determine the ending handle of the last cached characteristic. */
Gap::Handle_t startHandle = characteristics[characteristicIndex - 1].getValueHandle() + 1;
Gap::Handle_t endHandle = services[serviceIndex].getEndHandle();
resetDiscoveredCharacteristics(); /* Note: resetDiscoveredCharacteristics() must come after fetching start and end Handles. */
if(state != CHARACTERISTIC_DISCOVERY_ACTIVE) {
return;
}
if (startHandle < endHandle) {
ble_gattc_handle_range_t handleRange = {
.start_handle = startHandle,
.end_handle = endHandle
};
if (sd_ble_gattc_characteristics_discover(connHandle, &handleRange) != NRF_SUCCESS) {
terminateCharacteristicDiscovery();
}
} else {
Gap::Handle_t startHandle = characteristics[characteristicIndex - 1].getValueHandle() + 1;
Gap::Handle_t endHandle = services[serviceIndex].getEndHandle();
resetDiscoveredCharacteristics(); /* Note: resetDiscoveredCharacteristics() must come after fetching start and end Handles. */
if (startHandle < endHandle) {
ble_gattc_handle_range_t handleRange = {
.start_handle = startHandle,
.end_handle = endHandle
};
if (sd_ble_gattc_characteristics_discover(connHandle, &handleRange) != NRF_SUCCESS) {
terminateCharacteristicDiscovery();
}
} else {
terminateCharacteristicDiscovery();
}
}