add CharUUIDDiscoveryQueue

master
Rohit Grover 2015-05-27 13:22:23 +01:00
parent 30b9f534cd
commit 579beff995
2 changed files with 126 additions and 9 deletions

View File

@ -136,14 +136,39 @@ NordicServiceDiscovery::ServiceUUIDDiscoveryQueue::triggerFirst(void)
}
}
void
NordicServiceDiscovery::CharUUIDDiscoveryQueue::triggerFirst(void)
{
while (numIndices) { /* loop until a call to char_value_by_uuid_read() succeeds or we run out of pending indices. */
parentDiscoveryObject->state = DISCOVER_CHARACTERISTIC_UUIDS;
unsigned charIndex = getFirst();
ble_uuid_t uuid = {
.uuid = BLE_UUID_CHARACTERISTIC,
.type = BLE_UUID_TYPE_BLE,
};
ble_gattc_handle_range_t handleRange = {
.start_handle = parentDiscoveryObject->characteristics[charIndex].getDeclHandle(),
.end_handle = parentDiscoveryObject->characteristics[charIndex].getDeclHandle() + 1,
};
if (sd_ble_gattc_char_value_by_uuid_read(parentDiscoveryObject->connHandle, &uuid, &handleRange) == NRF_SUCCESS) {
return;
}
/* Skip this service if we fail to launch a read for its service-declaration
* attribute. Its UUID will remain INVALID, and it may not match any filters. */
dequeue();
}
/* Switch back to service discovery upon exhausting the service-indices pending UUID discovery. */
if (parentDiscoveryObject->state == DISCOVER_CHARACTERISTIC_UUIDS) {
parentDiscoveryObject->state = CHARACTERISTIC_DISCOVERY_ACTIVE;
}
}
void
NordicServiceDiscovery::processDiscoverUUIDResponse(const ble_gattc_evt_char_val_by_uuid_read_rsp_t *response)
{
// printf("BLE_GATTC_EVT_CHAR_VAL_BY_UUID_READ_RSP: count %u, len %u\r\n", response->count, response->value_len);
// for (unsigned i = 0; i < response->value_len; i++) {
// printf("%02x ", response->handle_value[0].p_value[i]);
// }
// printf("\r\n");
if (state == DISCOVER_SERVICE_UUIDS) {
if ((response->count == 1) && (response->value_len == UUID::LENGTH_OF_LONG_UUID)) {
UUID::LongUUIDBytes_t uuid;
@ -156,6 +181,23 @@ NordicServiceDiscovery::processDiscoverUUIDResponse(const ble_gattc_evt_char_val
services[serviceIndex].setupLongUUID(uuid);
serviceUUIDDiscoveryQueue.triggerFirst();
} else {
serviceUUIDDiscoveryQueue.dequeue();
}
} else if (state == DISCOVER_CHARACTERISTIC_UUIDS) {
if ((response->count == 1) && (response->value_len == UUID::LENGTH_OF_LONG_UUID + 1 /* props */ + 2 /* value handle */)) {
UUID::LongUUIDBytes_t uuid;
/* Switch longUUID bytes to MSB */
for (unsigned i = 0; i < UUID::LENGTH_OF_LONG_UUID; i++) {
uuid[i] = response->handle_value[0].p_value[3 + UUID::LENGTH_OF_LONG_UUID - 1 - i];
}
unsigned charIndex = charUUIDDiscoveryQueue.dequeue();
characteristics[charIndex].setupLongUUID(uuid);
charUUIDDiscoveryQueue.triggerFirst();
} else {
charUUIDDiscoveryQueue.dequeue();
}
}
}
@ -201,11 +243,24 @@ NordicServiceDiscovery::setupDiscoveredCharacteristics(const ble_gattc_evt_char_
numCharacteristics = BLE_DB_DISCOVERY_MAX_CHAR_PER_SRV;
}
charUUIDDiscoveryQueue.reset();
for (unsigned charIndex = 0; charIndex < numCharacteristics; charIndex++) {
characteristics[charIndex].setup(response->chars[charIndex].uuid.uuid,
*(const uint8_t *)(&response->chars[charIndex].char_props),
response->chars[charIndex].handle_decl,
response->chars[charIndex].handle_value);
if (response->chars[charIndex].uuid.type == BLE_UUID_TYPE_UNKNOWN) {
charUUIDDiscoveryQueue.enqueue(charIndex);
characteristics[charIndex].setup(*(const uint8_t *)(&response->chars[charIndex].char_props),
response->chars[charIndex].handle_decl,
response->chars[charIndex].handle_value);
} else {
characteristics[charIndex].setup(response->chars[charIndex].uuid.uuid,
*(const uint8_t *)(&response->chars[charIndex].char_props),
response->chars[charIndex].handle_decl,
response->chars[charIndex].handle_value);
}
}
/* Trigger discovery of char UUID if necessary. */
if (charUUIDDiscoveryQueue.getCount()) {
charUUIDDiscoveryQueue.triggerFirst();
}
}

View File

@ -41,6 +41,7 @@ public:
services(),
characteristics(),
serviceUUIDDiscoveryQueue(this),
charUUIDDiscoveryQueue(this),
onTerminationCallback(NULL) {
/* empty */
}
@ -167,6 +168,65 @@ private:
};
friend class ServiceUUIDDiscoveryQueue;
/**
* A datatype to contain characteristic-indices for which long UUIDs need to
* be discovered using read_val_by_uuid().
*/
class CharUUIDDiscoveryQueue {
public:
CharUUIDDiscoveryQueue(NordicServiceDiscovery *parent) :
numIndices(0),
charIndices(),
parentDiscoveryObject(parent) {
/* empty */
}
public:
void reset(void) {
numIndices = 0;
for (unsigned i = 0; i < BLE_DB_DISCOVERY_MAX_SRV; i++) {
charIndices[i] = INVALID_INDEX;
}
}
void enqueue(int serviceIndex) {
charIndices[numIndices++] = serviceIndex;
}
int dequeue(void) {
if (numIndices == 0) {
return INVALID_INDEX;
}
unsigned valueToReturn = charIndices[0];
numIndices--;
for (unsigned i = 0; i < numIndices; i++) {
charIndices[i] = charIndices[i + 1];
}
return valueToReturn;
}
unsigned getFirst(void) const {
return charIndices[0];
}
size_t getCount(void) const {
return numIndices;
}
/**
* Trigger UUID discovery for the first of the enqueued charIndices.
*/
void triggerFirst(void);
private:
static const int INVALID_INDEX = -1;
private:
size_t numIndices;
int charIndices[BLE_DB_DISCOVERY_MAX_CHAR_PER_SRV];
NordicServiceDiscovery *parentDiscoveryObject;
};
friend class CharUUIDDiscoveryQueue;
private:
friend void bleGattcEventHandler(const ble_evt_t *p_ble_evt);
void progressCharacteristicDiscovery(void);
@ -183,6 +243,7 @@ private:
SERVICE_DISCOVERY_ACTIVE,
CHARACTERISTIC_DISCOVERY_ACTIVE,
DISCOVER_SERVICE_UUIDS,
DISCOVER_CHARACTERISTIC_UUIDS,
} state;
DiscoveredService services[BLE_DB_DISCOVERY_MAX_SRV]; /**< Information related to the current service being discovered.
@ -190,6 +251,7 @@ private:
DiscoveredCharacteristic characteristics[BLE_DB_DISCOVERY_MAX_CHAR_PER_SRV];
ServiceUUIDDiscoveryQueue serviceUUIDDiscoveryQueue;
CharUUIDDiscoveryQueue charUUIDDiscoveryQueue;
TerminationCallback_t onTerminationCallback;
};