Nordic stack and drivers for the mbed BLE API

Fork of nRF51822 by Nordic Semiconductor

Committer:
Vincent Coubard
Date:
Wed Sep 14 14:39:43 2016 +0100
Revision:
638:c90ae1400bf2
Sync with bdab10dc0f90748b6989c8b577771bb403ca6bd8 from ARMmbed/mbed-os.

Who changed what in which revision?

UserRevisionLine numberNew contents of line
Vincent Coubard 638:c90ae1400bf2 1 /* mbed Microcontroller Library
Vincent Coubard 638:c90ae1400bf2 2 * Copyright (c) 2006-2013 ARM Limited
Vincent Coubard 638:c90ae1400bf2 3 *
Vincent Coubard 638:c90ae1400bf2 4 * Licensed under the Apache License, Version 2.0 (the "License");
Vincent Coubard 638:c90ae1400bf2 5 * you may not use this file except in compliance with the License.
Vincent Coubard 638:c90ae1400bf2 6 * You may obtain a copy of the License at
Vincent Coubard 638:c90ae1400bf2 7 *
Vincent Coubard 638:c90ae1400bf2 8 * http://www.apache.org/licenses/LICENSE-2.0
Vincent Coubard 638:c90ae1400bf2 9 *
Vincent Coubard 638:c90ae1400bf2 10 * Unless required by applicable law or agreed to in writing, software
Vincent Coubard 638:c90ae1400bf2 11 * distributed under the License is distributed on an "AS IS" BASIS,
Vincent Coubard 638:c90ae1400bf2 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
Vincent Coubard 638:c90ae1400bf2 13 * See the License for the specific language governing permissions and
Vincent Coubard 638:c90ae1400bf2 14 * limitations under the License.
Vincent Coubard 638:c90ae1400bf2 15 */
Vincent Coubard 638:c90ae1400bf2 16
Vincent Coubard 638:c90ae1400bf2 17 #include "nRF5xServiceDiscovery.h"
Vincent Coubard 638:c90ae1400bf2 18
Vincent Coubard 638:c90ae1400bf2 19 ble_error_t
Vincent Coubard 638:c90ae1400bf2 20 nRF5xServiceDiscovery::launchCharacteristicDiscovery(Gap::Handle_t connectionHandle,
Vincent Coubard 638:c90ae1400bf2 21 Gap::Handle_t startHandle,
Vincent Coubard 638:c90ae1400bf2 22 Gap::Handle_t endHandle)
Vincent Coubard 638:c90ae1400bf2 23 {
Vincent Coubard 638:c90ae1400bf2 24 characteristicDiscoveryStarted(connectionHandle);
Vincent Coubard 638:c90ae1400bf2 25
Vincent Coubard 638:c90ae1400bf2 26 ble_gattc_handle_range_t handleRange = {
Vincent Coubard 638:c90ae1400bf2 27 .start_handle = startHandle,
Vincent Coubard 638:c90ae1400bf2 28 .end_handle = endHandle
Vincent Coubard 638:c90ae1400bf2 29 };
Vincent Coubard 638:c90ae1400bf2 30 uint32_t rc = sd_ble_gattc_characteristics_discover(connectionHandle, &handleRange);
Vincent Coubard 638:c90ae1400bf2 31 ble_error_t err = BLE_ERROR_NONE;
Vincent Coubard 638:c90ae1400bf2 32
Vincent Coubard 638:c90ae1400bf2 33 switch (rc) {
Vincent Coubard 638:c90ae1400bf2 34 case NRF_SUCCESS:
Vincent Coubard 638:c90ae1400bf2 35 err = BLE_ERROR_NONE;
Vincent Coubard 638:c90ae1400bf2 36 break;
Vincent Coubard 638:c90ae1400bf2 37 case BLE_ERROR_INVALID_CONN_HANDLE:
Vincent Coubard 638:c90ae1400bf2 38 case NRF_ERROR_INVALID_ADDR:
Vincent Coubard 638:c90ae1400bf2 39 err = BLE_ERROR_INVALID_PARAM;
Vincent Coubard 638:c90ae1400bf2 40 break;
Vincent Coubard 638:c90ae1400bf2 41 case NRF_ERROR_BUSY:
Vincent Coubard 638:c90ae1400bf2 42 err = BLE_STACK_BUSY;
Vincent Coubard 638:c90ae1400bf2 43 break;
Vincent Coubard 638:c90ae1400bf2 44 case NRF_ERROR_INVALID_STATE:
Vincent Coubard 638:c90ae1400bf2 45 err = BLE_ERROR_INVALID_STATE;
Vincent Coubard 638:c90ae1400bf2 46 break;
Vincent Coubard 638:c90ae1400bf2 47 default:
Vincent Coubard 638:c90ae1400bf2 48 err = BLE_ERROR_UNSPECIFIED;
Vincent Coubard 638:c90ae1400bf2 49 break;
Vincent Coubard 638:c90ae1400bf2 50 }
Vincent Coubard 638:c90ae1400bf2 51
Vincent Coubard 638:c90ae1400bf2 52 if (err) {
Vincent Coubard 638:c90ae1400bf2 53 terminateCharacteristicDiscovery(err);
Vincent Coubard 638:c90ae1400bf2 54 }
Vincent Coubard 638:c90ae1400bf2 55 return err;
Vincent Coubard 638:c90ae1400bf2 56 }
Vincent Coubard 638:c90ae1400bf2 57
Vincent Coubard 638:c90ae1400bf2 58 void
Vincent Coubard 638:c90ae1400bf2 59 nRF5xServiceDiscovery::setupDiscoveredServices(const ble_gattc_evt_prim_srvc_disc_rsp_t *response)
Vincent Coubard 638:c90ae1400bf2 60 {
Vincent Coubard 638:c90ae1400bf2 61 serviceIndex = 0;
Vincent Coubard 638:c90ae1400bf2 62 numServices = response->count;
Vincent Coubard 638:c90ae1400bf2 63
Vincent Coubard 638:c90ae1400bf2 64 /* Account for the limitation on the number of discovered services we can handle at a time. */
Vincent Coubard 638:c90ae1400bf2 65 if (numServices > BLE_DB_DISCOVERY_MAX_SRV) {
Vincent Coubard 638:c90ae1400bf2 66 numServices = BLE_DB_DISCOVERY_MAX_SRV;
Vincent Coubard 638:c90ae1400bf2 67 }
Vincent Coubard 638:c90ae1400bf2 68
Vincent Coubard 638:c90ae1400bf2 69 serviceUUIDDiscoveryQueue.reset();
Vincent Coubard 638:c90ae1400bf2 70 for (unsigned i = 0; i < numServices; ++i) {
Vincent Coubard 638:c90ae1400bf2 71 if (response->services[i].uuid.type == BLE_UUID_TYPE_UNKNOWN) {
Vincent Coubard 638:c90ae1400bf2 72 serviceUUIDDiscoveryQueue.enqueue(i);
Vincent Coubard 638:c90ae1400bf2 73 services[i].setup(response->services[i].handle_range.start_handle,
Vincent Coubard 638:c90ae1400bf2 74 response->services[i].handle_range.end_handle);
Vincent Coubard 638:c90ae1400bf2 75 } else {
Vincent Coubard 638:c90ae1400bf2 76 services[i].setup(response->services[i].uuid.uuid,
Vincent Coubard 638:c90ae1400bf2 77 response->services[i].handle_range.start_handle,
Vincent Coubard 638:c90ae1400bf2 78 response->services[i].handle_range.end_handle);
Vincent Coubard 638:c90ae1400bf2 79 }
Vincent Coubard 638:c90ae1400bf2 80 }
Vincent Coubard 638:c90ae1400bf2 81
Vincent Coubard 638:c90ae1400bf2 82 /* Trigger discovery of service UUID if necessary. */
Vincent Coubard 638:c90ae1400bf2 83 if (serviceUUIDDiscoveryQueue.getCount()) {
Vincent Coubard 638:c90ae1400bf2 84 serviceUUIDDiscoveryQueue.triggerFirst();
Vincent Coubard 638:c90ae1400bf2 85 }
Vincent Coubard 638:c90ae1400bf2 86 }
Vincent Coubard 638:c90ae1400bf2 87
Vincent Coubard 638:c90ae1400bf2 88 void
Vincent Coubard 638:c90ae1400bf2 89 nRF5xServiceDiscovery::setupDiscoveredCharacteristics(const ble_gattc_evt_char_disc_rsp_t *response)
Vincent Coubard 638:c90ae1400bf2 90 {
Vincent Coubard 638:c90ae1400bf2 91 numCharacteristics = response->count;
Vincent Coubard 638:c90ae1400bf2 92
Vincent Coubard 638:c90ae1400bf2 93 /* Account for the limitation on the number of discovered characteristics we can handle at a time. */
Vincent Coubard 638:c90ae1400bf2 94 if (numCharacteristics > BLE_DB_DISCOVERY_MAX_CHAR_PER_SRV) {
Vincent Coubard 638:c90ae1400bf2 95 numCharacteristics = BLE_DB_DISCOVERY_MAX_CHAR_PER_SRV;
Vincent Coubard 638:c90ae1400bf2 96 }
Vincent Coubard 638:c90ae1400bf2 97
Vincent Coubard 638:c90ae1400bf2 98 charUUIDDiscoveryQueue.reset();
Vincent Coubard 638:c90ae1400bf2 99 for (unsigned charIndex = 0; charIndex < numCharacteristics; charIndex++) {
Vincent Coubard 638:c90ae1400bf2 100 if (response->chars[charIndex].uuid.type == BLE_UUID_TYPE_UNKNOWN) {
Vincent Coubard 638:c90ae1400bf2 101 charUUIDDiscoveryQueue.enqueue(charIndex);
Vincent Coubard 638:c90ae1400bf2 102 characteristics[charIndex].setup(gattc,
Vincent Coubard 638:c90ae1400bf2 103 connHandle,
Vincent Coubard 638:c90ae1400bf2 104 response->chars[charIndex].char_props,
Vincent Coubard 638:c90ae1400bf2 105 response->chars[charIndex].handle_decl,
Vincent Coubard 638:c90ae1400bf2 106 response->chars[charIndex].handle_value);
Vincent Coubard 638:c90ae1400bf2 107 } else {
Vincent Coubard 638:c90ae1400bf2 108 characteristics[charIndex].setup(gattc,
Vincent Coubard 638:c90ae1400bf2 109 connHandle,
Vincent Coubard 638:c90ae1400bf2 110 response->chars[charIndex].uuid.uuid,
Vincent Coubard 638:c90ae1400bf2 111 response->chars[charIndex].char_props,
Vincent Coubard 638:c90ae1400bf2 112 response->chars[charIndex].handle_decl,
Vincent Coubard 638:c90ae1400bf2 113 response->chars[charIndex].handle_value);
Vincent Coubard 638:c90ae1400bf2 114 }
Vincent Coubard 638:c90ae1400bf2 115 }
Vincent Coubard 638:c90ae1400bf2 116
Vincent Coubard 638:c90ae1400bf2 117 /* Trigger discovery of char UUID if necessary. */
Vincent Coubard 638:c90ae1400bf2 118 if (charUUIDDiscoveryQueue.getCount()) {
Vincent Coubard 638:c90ae1400bf2 119 charUUIDDiscoveryQueue.triggerFirst();
Vincent Coubard 638:c90ae1400bf2 120 }
Vincent Coubard 638:c90ae1400bf2 121 }
Vincent Coubard 638:c90ae1400bf2 122
Vincent Coubard 638:c90ae1400bf2 123 void
Vincent Coubard 638:c90ae1400bf2 124 nRF5xServiceDiscovery::progressCharacteristicDiscovery(void)
Vincent Coubard 638:c90ae1400bf2 125 {
Vincent Coubard 638:c90ae1400bf2 126 if (state != CHARACTERISTIC_DISCOVERY_ACTIVE) {
Vincent Coubard 638:c90ae1400bf2 127 return;
Vincent Coubard 638:c90ae1400bf2 128 }
Vincent Coubard 638:c90ae1400bf2 129
Vincent Coubard 638:c90ae1400bf2 130 if ((discoveredCharacteristic != nRF5xDiscoveredCharacteristic()) && (numCharacteristics > 0)) {
Vincent Coubard 638:c90ae1400bf2 131 discoveredCharacteristic.setLastHandle(characteristics[0].getDeclHandle() - 1);
Vincent Coubard 638:c90ae1400bf2 132
Vincent Coubard 638:c90ae1400bf2 133 if ((matchingCharacteristicUUID == UUID::ShortUUIDBytes_t(BLE_UUID_UNKNOWN)) ||
Vincent Coubard 638:c90ae1400bf2 134 ((matchingCharacteristicUUID == discoveredCharacteristic.getUUID()) &&
Vincent Coubard 638:c90ae1400bf2 135 (matchingServiceUUID != UUID::ShortUUIDBytes_t(BLE_UUID_UNKNOWN)))) {
Vincent Coubard 638:c90ae1400bf2 136 if (characteristicCallback) {
Vincent Coubard 638:c90ae1400bf2 137 characteristicCallback(&discoveredCharacteristic);
Vincent Coubard 638:c90ae1400bf2 138 }
Vincent Coubard 638:c90ae1400bf2 139 }
Vincent Coubard 638:c90ae1400bf2 140 }
Vincent Coubard 638:c90ae1400bf2 141
Vincent Coubard 638:c90ae1400bf2 142 for (uint8_t i = 0; i < numCharacteristics; ++i) {
Vincent Coubard 638:c90ae1400bf2 143 if (state != CHARACTERISTIC_DISCOVERY_ACTIVE) {
Vincent Coubard 638:c90ae1400bf2 144 return;
Vincent Coubard 638:c90ae1400bf2 145 }
Vincent Coubard 638:c90ae1400bf2 146
Vincent Coubard 638:c90ae1400bf2 147 if (i == (numCharacteristics - 1)) {
Vincent Coubard 638:c90ae1400bf2 148 discoveredCharacteristic = characteristics[i];
Vincent Coubard 638:c90ae1400bf2 149 break;
Vincent Coubard 638:c90ae1400bf2 150 } else {
Vincent Coubard 638:c90ae1400bf2 151 characteristics[i].setLastHandle(characteristics[i + 1].getDeclHandle() - 1);
Vincent Coubard 638:c90ae1400bf2 152 }
Vincent Coubard 638:c90ae1400bf2 153
Vincent Coubard 638:c90ae1400bf2 154 if ((matchingCharacteristicUUID == UUID::ShortUUIDBytes_t(BLE_UUID_UNKNOWN)) ||
Vincent Coubard 638:c90ae1400bf2 155 ((matchingCharacteristicUUID == characteristics[i].getUUID()) &&
Vincent Coubard 638:c90ae1400bf2 156 (matchingServiceUUID != UUID::ShortUUIDBytes_t(BLE_UUID_UNKNOWN)))) {
Vincent Coubard 638:c90ae1400bf2 157 if (characteristicCallback) {
Vincent Coubard 638:c90ae1400bf2 158 characteristicCallback(&characteristics[i]);
Vincent Coubard 638:c90ae1400bf2 159 }
Vincent Coubard 638:c90ae1400bf2 160 }
Vincent Coubard 638:c90ae1400bf2 161 }
Vincent Coubard 638:c90ae1400bf2 162
Vincent Coubard 638:c90ae1400bf2 163 if (state != CHARACTERISTIC_DISCOVERY_ACTIVE) {
Vincent Coubard 638:c90ae1400bf2 164 return;
Vincent Coubard 638:c90ae1400bf2 165 }
Vincent Coubard 638:c90ae1400bf2 166
Vincent Coubard 638:c90ae1400bf2 167 Gap::Handle_t startHandle = (numCharacteristics > 0) ? characteristics[numCharacteristics - 1].getValueHandle() + 1 : SRV_DISC_END_HANDLE;
Vincent Coubard 638:c90ae1400bf2 168 Gap::Handle_t endHandle = services[serviceIndex].getEndHandle();
Vincent Coubard 638:c90ae1400bf2 169 resetDiscoveredCharacteristics(); /* Note: resetDiscoveredCharacteristics() must come after fetching start and end Handles. */
Vincent Coubard 638:c90ae1400bf2 170
Vincent Coubard 638:c90ae1400bf2 171 if (startHandle < endHandle) {
Vincent Coubard 638:c90ae1400bf2 172 ble_gattc_handle_range_t handleRange = {
Vincent Coubard 638:c90ae1400bf2 173 .start_handle = startHandle,
Vincent Coubard 638:c90ae1400bf2 174 .end_handle = endHandle
Vincent Coubard 638:c90ae1400bf2 175 };
Vincent Coubard 638:c90ae1400bf2 176 if (sd_ble_gattc_characteristics_discover(connHandle, &handleRange) != NRF_SUCCESS) {
Vincent Coubard 638:c90ae1400bf2 177 terminateCharacteristicDiscovery(BLE_ERROR_UNSPECIFIED);
Vincent Coubard 638:c90ae1400bf2 178 }
Vincent Coubard 638:c90ae1400bf2 179 } else {
Vincent Coubard 638:c90ae1400bf2 180 terminateCharacteristicDiscovery(BLE_ERROR_NONE);
Vincent Coubard 638:c90ae1400bf2 181 }
Vincent Coubard 638:c90ae1400bf2 182 }
Vincent Coubard 638:c90ae1400bf2 183
Vincent Coubard 638:c90ae1400bf2 184 void
Vincent Coubard 638:c90ae1400bf2 185 nRF5xServiceDiscovery::progressServiceDiscovery(void)
Vincent Coubard 638:c90ae1400bf2 186 {
Vincent Coubard 638:c90ae1400bf2 187 /* Iterate through the previously discovered services cached in services[]. */
Vincent Coubard 638:c90ae1400bf2 188 while ((state == SERVICE_DISCOVERY_ACTIVE) && (serviceIndex < numServices)) {
Vincent Coubard 638:c90ae1400bf2 189 if ((matchingServiceUUID == UUID::ShortUUIDBytes_t(BLE_UUID_UNKNOWN)) ||
Vincent Coubard 638:c90ae1400bf2 190 (matchingServiceUUID == services[serviceIndex].getUUID())) {
Vincent Coubard 638:c90ae1400bf2 191
Vincent Coubard 638:c90ae1400bf2 192 if (serviceCallback && (matchingCharacteristicUUID == UUID::ShortUUIDBytes_t(BLE_UUID_UNKNOWN))) {
Vincent Coubard 638:c90ae1400bf2 193 serviceCallback(&services[serviceIndex]);
Vincent Coubard 638:c90ae1400bf2 194 }
Vincent Coubard 638:c90ae1400bf2 195
Vincent Coubard 638:c90ae1400bf2 196 if ((state == SERVICE_DISCOVERY_ACTIVE) && characteristicCallback) {
Vincent Coubard 638:c90ae1400bf2 197 launchCharacteristicDiscovery(connHandle, services[serviceIndex].getStartHandle(), services[serviceIndex].getEndHandle());
Vincent Coubard 638:c90ae1400bf2 198 } else {
Vincent Coubard 638:c90ae1400bf2 199 serviceIndex++;
Vincent Coubard 638:c90ae1400bf2 200 }
Vincent Coubard 638:c90ae1400bf2 201 } else {
Vincent Coubard 638:c90ae1400bf2 202 serviceIndex++;
Vincent Coubard 638:c90ae1400bf2 203 }
Vincent Coubard 638:c90ae1400bf2 204 }
Vincent Coubard 638:c90ae1400bf2 205
Vincent Coubard 638:c90ae1400bf2 206 /* Relaunch discovery of new services beyond the last entry cached in services[]. */
Vincent Coubard 638:c90ae1400bf2 207 if ((state == SERVICE_DISCOVERY_ACTIVE) && (numServices > 0) && (serviceIndex > 0)) {
Vincent Coubard 638:c90ae1400bf2 208 /* Determine the ending handle of the last cached service. */
Vincent Coubard 638:c90ae1400bf2 209 Gap::Handle_t endHandle = services[serviceIndex - 1].getEndHandle();
Vincent Coubard 638:c90ae1400bf2 210 resetDiscoveredServices(); /* Note: resetDiscoveredServices() must come after fetching endHandle. */
Vincent Coubard 638:c90ae1400bf2 211
Vincent Coubard 638:c90ae1400bf2 212 if (endHandle == SRV_DISC_END_HANDLE) {
Vincent Coubard 638:c90ae1400bf2 213 terminateServiceDiscovery();
Vincent Coubard 638:c90ae1400bf2 214 } else {
Vincent Coubard 638:c90ae1400bf2 215 // the next service is located after the last handle discovered
Vincent Coubard 638:c90ae1400bf2 216 // Launch a new discovery from [endHandle + 1 : 0xFFFF]
Vincent Coubard 638:c90ae1400bf2 217 if (sd_ble_gattc_primary_services_discover(connHandle, endHandle + 1, NULL) != NRF_SUCCESS) {
Vincent Coubard 638:c90ae1400bf2 218 terminateServiceDiscovery();
Vincent Coubard 638:c90ae1400bf2 219 }
Vincent Coubard 638:c90ae1400bf2 220 }
Vincent Coubard 638:c90ae1400bf2 221 }
Vincent Coubard 638:c90ae1400bf2 222 }
Vincent Coubard 638:c90ae1400bf2 223
Vincent Coubard 638:c90ae1400bf2 224 void
Vincent Coubard 638:c90ae1400bf2 225 nRF5xServiceDiscovery::ServiceUUIDDiscoveryQueue::triggerFirst(void)
Vincent Coubard 638:c90ae1400bf2 226 {
Vincent Coubard 638:c90ae1400bf2 227 while (numIndices) { /* loop until a call to char_value_by_uuid_read() succeeds or we run out of pending indices. */
Vincent Coubard 638:c90ae1400bf2 228 parentDiscoveryObject->state = DISCOVER_SERVICE_UUIDS;
Vincent Coubard 638:c90ae1400bf2 229
Vincent Coubard 638:c90ae1400bf2 230 unsigned serviceIndex = getFirst();
Vincent Coubard 638:c90ae1400bf2 231 ble_uuid_t uuid = {
Vincent Coubard 638:c90ae1400bf2 232 .uuid = BLE_UUID_SERVICE_PRIMARY,
Vincent Coubard 638:c90ae1400bf2 233 .type = BLE_UUID_TYPE_BLE,
Vincent Coubard 638:c90ae1400bf2 234 };
Vincent Coubard 638:c90ae1400bf2 235 ble_gattc_handle_range_t handleRange = {
Vincent Coubard 638:c90ae1400bf2 236 .start_handle = parentDiscoveryObject->services[serviceIndex].getStartHandle(),
Vincent Coubard 638:c90ae1400bf2 237 .end_handle = parentDiscoveryObject->services[serviceIndex].getEndHandle(),
Vincent Coubard 638:c90ae1400bf2 238 };
Vincent Coubard 638:c90ae1400bf2 239 if (sd_ble_gattc_char_value_by_uuid_read(parentDiscoveryObject->connHandle, &uuid, &handleRange) == NRF_SUCCESS) {
Vincent Coubard 638:c90ae1400bf2 240 return;
Vincent Coubard 638:c90ae1400bf2 241 }
Vincent Coubard 638:c90ae1400bf2 242
Vincent Coubard 638:c90ae1400bf2 243 /* Skip this service if we fail to launch a read for its service-declaration
Vincent Coubard 638:c90ae1400bf2 244 * attribute. Its UUID will remain INVALID, and it may not match any filters. */
Vincent Coubard 638:c90ae1400bf2 245 dequeue();
Vincent Coubard 638:c90ae1400bf2 246 }
Vincent Coubard 638:c90ae1400bf2 247
Vincent Coubard 638:c90ae1400bf2 248 /* Switch back to service discovery upon exhausting the service-indices pending UUID discovery. */
Vincent Coubard 638:c90ae1400bf2 249 if (parentDiscoveryObject->state == DISCOVER_SERVICE_UUIDS) {
Vincent Coubard 638:c90ae1400bf2 250 parentDiscoveryObject->state = SERVICE_DISCOVERY_ACTIVE;
Vincent Coubard 638:c90ae1400bf2 251 }
Vincent Coubard 638:c90ae1400bf2 252 }
Vincent Coubard 638:c90ae1400bf2 253
Vincent Coubard 638:c90ae1400bf2 254 void
Vincent Coubard 638:c90ae1400bf2 255 nRF5xServiceDiscovery::CharUUIDDiscoveryQueue::triggerFirst(void)
Vincent Coubard 638:c90ae1400bf2 256 {
Vincent Coubard 638:c90ae1400bf2 257 while (numIndices) { /* loop until a call to char_value_by_uuid_read() succeeds or we run out of pending indices. */
Vincent Coubard 638:c90ae1400bf2 258 parentDiscoveryObject->state = DISCOVER_CHARACTERISTIC_UUIDS;
Vincent Coubard 638:c90ae1400bf2 259
Vincent Coubard 638:c90ae1400bf2 260 unsigned charIndex = getFirst();
Vincent Coubard 638:c90ae1400bf2 261 ble_uuid_t uuid = {
Vincent Coubard 638:c90ae1400bf2 262 .uuid = BLE_UUID_CHARACTERISTIC,
Vincent Coubard 638:c90ae1400bf2 263 .type = BLE_UUID_TYPE_BLE,
Vincent Coubard 638:c90ae1400bf2 264 };
Vincent Coubard 638:c90ae1400bf2 265 ble_gattc_handle_range_t handleRange = { };
Vincent Coubard 638:c90ae1400bf2 266 handleRange.start_handle = parentDiscoveryObject->characteristics[charIndex].getDeclHandle();
Vincent Coubard 638:c90ae1400bf2 267 handleRange.end_handle = parentDiscoveryObject->characteristics[charIndex].getDeclHandle() + 1;
Vincent Coubard 638:c90ae1400bf2 268 if (sd_ble_gattc_char_value_by_uuid_read(parentDiscoveryObject->connHandle, &uuid, &handleRange) == NRF_SUCCESS) {
Vincent Coubard 638:c90ae1400bf2 269 return;
Vincent Coubard 638:c90ae1400bf2 270 }
Vincent Coubard 638:c90ae1400bf2 271
Vincent Coubard 638:c90ae1400bf2 272 /* Skip this service if we fail to launch a read for its service-declaration
Vincent Coubard 638:c90ae1400bf2 273 * attribute. Its UUID will remain INVALID, and it may not match any filters. */
Vincent Coubard 638:c90ae1400bf2 274 dequeue();
Vincent Coubard 638:c90ae1400bf2 275 }
Vincent Coubard 638:c90ae1400bf2 276
Vincent Coubard 638:c90ae1400bf2 277 /* Switch back to service discovery upon exhausting the service-indices pending UUID discovery. */
Vincent Coubard 638:c90ae1400bf2 278 if (parentDiscoveryObject->state == DISCOVER_CHARACTERISTIC_UUIDS) {
Vincent Coubard 638:c90ae1400bf2 279 parentDiscoveryObject->state = CHARACTERISTIC_DISCOVERY_ACTIVE;
Vincent Coubard 638:c90ae1400bf2 280 }
Vincent Coubard 638:c90ae1400bf2 281 }
Vincent Coubard 638:c90ae1400bf2 282
Vincent Coubard 638:c90ae1400bf2 283 void
Vincent Coubard 638:c90ae1400bf2 284 nRF5xServiceDiscovery::processDiscoverUUIDResponse(const ble_gattc_evt_char_val_by_uuid_read_rsp_t *response)
Vincent Coubard 638:c90ae1400bf2 285 {
Vincent Coubard 638:c90ae1400bf2 286 if (state == DISCOVER_SERVICE_UUIDS) {
Vincent Coubard 638:c90ae1400bf2 287 if ((response->count == 1) && (response->value_len == UUID::LENGTH_OF_LONG_UUID)) {
Vincent Coubard 638:c90ae1400bf2 288 UUID::LongUUIDBytes_t uuid;
Vincent Coubard 638:c90ae1400bf2 289 memcpy(uuid, response->handle_value[0].p_value, UUID::LENGTH_OF_LONG_UUID);
Vincent Coubard 638:c90ae1400bf2 290
Vincent Coubard 638:c90ae1400bf2 291 unsigned serviceIndex = serviceUUIDDiscoveryQueue.dequeue();
Vincent Coubard 638:c90ae1400bf2 292 services[serviceIndex].setupLongUUID(uuid, UUID::LSB);
Vincent Coubard 638:c90ae1400bf2 293
Vincent Coubard 638:c90ae1400bf2 294 serviceUUIDDiscoveryQueue.triggerFirst();
Vincent Coubard 638:c90ae1400bf2 295 } else {
Vincent Coubard 638:c90ae1400bf2 296 serviceUUIDDiscoveryQueue.dequeue();
Vincent Coubard 638:c90ae1400bf2 297 }
Vincent Coubard 638:c90ae1400bf2 298 } else if (state == DISCOVER_CHARACTERISTIC_UUIDS) {
Vincent Coubard 638:c90ae1400bf2 299 if ((response->count == 1) && (response->value_len == UUID::LENGTH_OF_LONG_UUID + 1 /* props */ + 2 /* value handle */)) {
Vincent Coubard 638:c90ae1400bf2 300 UUID::LongUUIDBytes_t uuid;
Vincent Coubard 638:c90ae1400bf2 301
Vincent Coubard 638:c90ae1400bf2 302 memcpy(uuid, &(response->handle_value[0].p_value[3]), UUID::LENGTH_OF_LONG_UUID);
Vincent Coubard 638:c90ae1400bf2 303
Vincent Coubard 638:c90ae1400bf2 304 unsigned charIndex = charUUIDDiscoveryQueue.dequeue();
Vincent Coubard 638:c90ae1400bf2 305 characteristics[charIndex].setupLongUUID(uuid, UUID::LSB);
Vincent Coubard 638:c90ae1400bf2 306
Vincent Coubard 638:c90ae1400bf2 307 charUUIDDiscoveryQueue.triggerFirst();
Vincent Coubard 638:c90ae1400bf2 308 } else {
Vincent Coubard 638:c90ae1400bf2 309 charUUIDDiscoveryQueue.dequeue();
Vincent Coubard 638:c90ae1400bf2 310 }
Vincent Coubard 638:c90ae1400bf2 311 }
Vincent Coubard 638:c90ae1400bf2 312 }