nordic

Fork of nRF51822 by Nordic Semiconductor

Committer:
rgrover1
Date:
Fri Jun 19 15:55:22 2015 +0100
Revision:
252:d4e0cf5e8751
Parent:
250:55aa8e43f532
Child:
253:4b3f294415f5
Synchronized with git rev 53f022f1
Author: Rohit Grover
move out progress*Discovery() into btle_discovery.cpp

Who changed what in which revision?

UserRevisionLine numberNew contents of line
rgrover1 244:a966506d1e5b 1 /* mbed Microcontroller Library
rgrover1 244:a966506d1e5b 2 * Copyright (c) 2006-2013 ARM Limited
rgrover1 244:a966506d1e5b 3 *
rgrover1 244:a966506d1e5b 4 * Licensed under the Apache License, Version 2.0 (the "License");
rgrover1 244:a966506d1e5b 5 * you may not use this file except in compliance with the License.
rgrover1 244:a966506d1e5b 6 * You may obtain a copy of the License at
rgrover1 244:a966506d1e5b 7 *
rgrover1 244:a966506d1e5b 8 * http://www.apache.org/licenses/LICENSE-2.0
rgrover1 244:a966506d1e5b 9 *
rgrover1 244:a966506d1e5b 10 * Unless required by applicable law or agreed to in writing, software
rgrover1 244:a966506d1e5b 11 * distributed under the License is distributed on an "AS IS" BASIS,
rgrover1 244:a966506d1e5b 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
rgrover1 244:a966506d1e5b 13 * See the License for the specific language governing permissions and
rgrover1 244:a966506d1e5b 14 * limitations under the License.
rgrover1 244:a966506d1e5b 15 */
rgrover1 244:a966506d1e5b 16
rgrover1 240:693a1f145b5a 17 #include "blecommon.h"
rgrover1 240:693a1f145b5a 18 #include "UUID.h"
rgrover1 240:693a1f145b5a 19 #include "Gap.h"
rgrover1 240:693a1f145b5a 20 #include "nrf_error.h"
rgrover1 240:693a1f145b5a 21 #include "btle_discovery.h"
rgrover1 240:693a1f145b5a 22 #include "ble_err.h"
rgrover1 244:a966506d1e5b 23
rgrover1 244:a966506d1e5b 24 static NordicServiceDiscovery discoverySingleton;
rgrover1 240:693a1f145b5a 25
rgrover1 240:693a1f145b5a 26 ble_error_t
rgrover1 240:693a1f145b5a 27 ServiceDiscovery::launch(Gap::Handle_t connectionHandle, ServiceCallback_t sc, CharacteristicCallback_t cc)
rgrover1 240:693a1f145b5a 28 {
rgrover1 244:a966506d1e5b 29 discoverySingleton.serviceDiscoveryStarted(connectionHandle);
rgrover1 250:55aa8e43f532 30 discoverySingleton.serviceCallback = sc;
rgrover1 250:55aa8e43f532 31 discoverySingleton.characteristicCallback = cc;
rgrover1 240:693a1f145b5a 32
rgrover1 240:693a1f145b5a 33 uint32_t rc;
rgrover1 249:71ef03789dd3 34 if ((rc = sd_ble_gattc_primary_services_discover(connectionHandle, NordicServiceDiscovery::SRV_DISC_START_HANDLE, NULL)) != NRF_SUCCESS) {
rgrover1 249:71ef03789dd3 35 discoverySingleton.terminate();
rgrover1 240:693a1f145b5a 36 switch (rc) {
rgrover1 240:693a1f145b5a 37 case NRF_ERROR_INVALID_PARAM:
rgrover1 240:693a1f145b5a 38 case BLE_ERROR_INVALID_CONN_HANDLE:
rgrover1 240:693a1f145b5a 39 return BLE_ERROR_INVALID_PARAM;
rgrover1 240:693a1f145b5a 40 case NRF_ERROR_BUSY:
rgrover1 240:693a1f145b5a 41 return BLE_STACK_BUSY;
rgrover1 240:693a1f145b5a 42 default:
rgrover1 240:693a1f145b5a 43 case NRF_ERROR_INVALID_STATE:
rgrover1 240:693a1f145b5a 44 return BLE_ERROR_INVALID_STATE;
rgrover1 240:693a1f145b5a 45 }
rgrover1 240:693a1f145b5a 46 }
rgrover1 240:693a1f145b5a 47
rgrover1 240:693a1f145b5a 48 return BLE_ERROR_NONE;
rgrover1 240:693a1f145b5a 49 }
rgrover1 240:693a1f145b5a 50
rgrover1 249:71ef03789dd3 51 void
rgrover1 249:71ef03789dd3 52 ServiceDiscovery::terminate(void)
rgrover1 249:71ef03789dd3 53 {
rgrover1 249:71ef03789dd3 54 discoverySingleton.terminateServiceDiscovery();
rgrover1 249:71ef03789dd3 55 }
rgrover1 249:71ef03789dd3 56
rgrover1 244:a966506d1e5b 57 ble_error_t
rgrover1 244:a966506d1e5b 58 NordicServiceDiscovery::launchCharacteristicDiscovery(Gap::Handle_t connectionHandle, Gap::Handle_t startHandle, Gap::Handle_t endHandle) {
rgrover1 244:a966506d1e5b 59 discoverySingleton.characteristicDiscoveryStarted(connectionHandle);
rgrover1 240:693a1f145b5a 60
rgrover1 240:693a1f145b5a 61 ble_gattc_handle_range_t handleRange = {
rgrover1 240:693a1f145b5a 62 .start_handle = startHandle,
rgrover1 240:693a1f145b5a 63 .end_handle = endHandle
rgrover1 240:693a1f145b5a 64 };
rgrover1 240:693a1f145b5a 65 uint32_t rc;
rgrover1 240:693a1f145b5a 66 if ((rc = sd_ble_gattc_characteristics_discover(connectionHandle, &handleRange)) != NRF_SUCCESS) {
rgrover1 244:a966506d1e5b 67 discoverySingleton.terminateCharacteristicDiscovery();
rgrover1 240:693a1f145b5a 68 switch (rc) {
rgrover1 240:693a1f145b5a 69 case BLE_ERROR_INVALID_CONN_HANDLE:
rgrover1 240:693a1f145b5a 70 case NRF_ERROR_INVALID_ADDR:
rgrover1 240:693a1f145b5a 71 return BLE_ERROR_INVALID_PARAM;
rgrover1 240:693a1f145b5a 72 case NRF_ERROR_BUSY:
rgrover1 240:693a1f145b5a 73 return BLE_STACK_BUSY;
rgrover1 240:693a1f145b5a 74 default:
rgrover1 240:693a1f145b5a 75 case NRF_ERROR_INVALID_STATE:
rgrover1 240:693a1f145b5a 76 return BLE_ERROR_INVALID_STATE;
rgrover1 240:693a1f145b5a 77 }
rgrover1 240:693a1f145b5a 78 }
rgrover1 240:693a1f145b5a 79
rgrover1 240:693a1f145b5a 80 return BLE_ERROR_NONE;
rgrover1 240:693a1f145b5a 81 }
rgrover1 240:693a1f145b5a 82
rgrover1 240:693a1f145b5a 83 void
rgrover1 241:75b69581d1dd 84 NordicServiceDiscovery::setupDiscoveredServices(const ble_gattc_evt_prim_srvc_disc_rsp_t *response)
rgrover1 240:693a1f145b5a 85 {
rgrover1 243:73fc02cc20b1 86 serviceIndex = 0;
rgrover1 243:73fc02cc20b1 87 numServices = response->count;
rgrover1 240:693a1f145b5a 88
rgrover1 240:693a1f145b5a 89 /* Account for the limitation on the number of discovered services we can handle at a time. */
rgrover1 243:73fc02cc20b1 90 if (numServices > BLE_DB_DISCOVERY_MAX_SRV) {
rgrover1 243:73fc02cc20b1 91 numServices = BLE_DB_DISCOVERY_MAX_SRV;
rgrover1 240:693a1f145b5a 92 }
rgrover1 240:693a1f145b5a 93
rgrover1 243:73fc02cc20b1 94 for (unsigned serviceIndex = 0; serviceIndex < numServices; serviceIndex++) {
rgrover1 240:693a1f145b5a 95 services[serviceIndex].setup(response->services[serviceIndex].uuid.uuid,
rgrover1 240:693a1f145b5a 96 response->services[serviceIndex].handle_range.start_handle,
rgrover1 240:693a1f145b5a 97 response->services[serviceIndex].handle_range.end_handle);
rgrover1 240:693a1f145b5a 98 }
rgrover1 240:693a1f145b5a 99 }
rgrover1 240:693a1f145b5a 100
rgrover1 240:693a1f145b5a 101 void
rgrover1 241:75b69581d1dd 102 NordicServiceDiscovery::setupDiscoveredCharacteristics(const ble_gattc_evt_char_disc_rsp_t *response)
rgrover1 240:693a1f145b5a 103 {
rgrover1 243:73fc02cc20b1 104 characteristicIndex = 0;
rgrover1 243:73fc02cc20b1 105 numCharacteristics = response->count;
rgrover1 240:693a1f145b5a 106
rgrover1 240:693a1f145b5a 107 /* Account for the limitation on the number of discovered characteristics we can handle at a time. */
rgrover1 243:73fc02cc20b1 108 if (numCharacteristics > BLE_DB_DISCOVERY_MAX_CHAR_PER_SRV) {
rgrover1 243:73fc02cc20b1 109 numCharacteristics = BLE_DB_DISCOVERY_MAX_CHAR_PER_SRV;
rgrover1 240:693a1f145b5a 110 }
rgrover1 240:693a1f145b5a 111
rgrover1 243:73fc02cc20b1 112 for (unsigned charIndex = 0; charIndex < numCharacteristics; charIndex++) {
rgrover1 240:693a1f145b5a 113 characteristics[charIndex].setup(response->chars[charIndex].uuid.uuid,
rgrover1 240:693a1f145b5a 114 *(const uint8_t *)(&response->chars[charIndex].char_props),
rgrover1 240:693a1f145b5a 115 response->chars[charIndex].handle_decl,
rgrover1 240:693a1f145b5a 116 response->chars[charIndex].handle_value);
rgrover1 240:693a1f145b5a 117 }
rgrover1 244:a966506d1e5b 118 }
rgrover1 244:a966506d1e5b 119
rgrover1 252:d4e0cf5e8751 120 void
rgrover1 252:d4e0cf5e8751 121 NordicServiceDiscovery::progressCharacteristicDiscovery(void)
rgrover1 252:d4e0cf5e8751 122 {
rgrover1 252:d4e0cf5e8751 123 while (cDiscoveryActive && (characteristicIndex < numCharacteristics)) {
rgrover1 252:d4e0cf5e8751 124 /* THIS IS WHERE THE CALLBACK WILL GO */
rgrover1 252:d4e0cf5e8751 125 printf("%x [%u]\r\n", characteristics[characteristicIndex].uuid, characteristics[characteristicIndex].valueHandle);
rgrover1 252:d4e0cf5e8751 126
rgrover1 252:d4e0cf5e8751 127 characteristicIndex++;
rgrover1 252:d4e0cf5e8751 128 }
rgrover1 252:d4e0cf5e8751 129
rgrover1 252:d4e0cf5e8751 130 if (cDiscoveryActive) {
rgrover1 252:d4e0cf5e8751 131 Gap::Handle_t startHandle = characteristics[characteristicIndex - 1].valueHandle + 1;
rgrover1 252:d4e0cf5e8751 132 Gap::Handle_t endHandle = services[serviceIndex].endHandle;
rgrover1 252:d4e0cf5e8751 133 resetDiscoveredCharacteristics();
rgrover1 252:d4e0cf5e8751 134
rgrover1 252:d4e0cf5e8751 135 if (startHandle < endHandle) {
rgrover1 252:d4e0cf5e8751 136 ble_gattc_handle_range_t handleRange = {
rgrover1 252:d4e0cf5e8751 137 .start_handle = startHandle,
rgrover1 252:d4e0cf5e8751 138 .end_handle = endHandle
rgrover1 252:d4e0cf5e8751 139 };
rgrover1 252:d4e0cf5e8751 140 printf("char discovery returned %u\r\n", sd_ble_gattc_characteristics_discover(connHandle, &handleRange));
rgrover1 252:d4e0cf5e8751 141 } else {
rgrover1 252:d4e0cf5e8751 142 terminateCharacteristicDiscovery();
rgrover1 252:d4e0cf5e8751 143 }
rgrover1 252:d4e0cf5e8751 144 }
rgrover1 252:d4e0cf5e8751 145 }
rgrover1 252:d4e0cf5e8751 146
rgrover1 252:d4e0cf5e8751 147 void
rgrover1 252:d4e0cf5e8751 148 NordicServiceDiscovery::progressServiceDiscovery(void)
rgrover1 252:d4e0cf5e8751 149 {
rgrover1 252:d4e0cf5e8751 150 while (sDiscoveryActive && (serviceIndex < numServices)) {
rgrover1 252:d4e0cf5e8751 151 /* THIS IS WHERE THE CALLBACK WILL GO */
rgrover1 252:d4e0cf5e8751 152 printf("%x [%u %u]\r\n", services[serviceIndex].uuid, services[serviceIndex].startHandle, services[serviceIndex].endHandle);
rgrover1 252:d4e0cf5e8751 153
rgrover1 252:d4e0cf5e8751 154 if (true) { /* characteristic discovery is optional. */
rgrover1 252:d4e0cf5e8751 155 launchCharacteristicDiscovery(connHandle, services[serviceIndex].startHandle, services[serviceIndex].endHandle);
rgrover1 252:d4e0cf5e8751 156 } else {
rgrover1 252:d4e0cf5e8751 157 serviceIndex++; /* Progress service index to keep discovery alive. */
rgrover1 252:d4e0cf5e8751 158 }
rgrover1 252:d4e0cf5e8751 159 }
rgrover1 252:d4e0cf5e8751 160 if (sDiscoveryActive && (numServices > 0) && (serviceIndex > 0)) {
rgrover1 252:d4e0cf5e8751 161 Gap::Handle_t endHandle = services[serviceIndex - 1].endHandle;
rgrover1 252:d4e0cf5e8751 162 resetDiscoveredServices();
rgrover1 252:d4e0cf5e8751 163
rgrover1 252:d4e0cf5e8751 164 printf("services discover returned %u\r\n", sd_ble_gattc_primary_services_discover(connHandle, endHandle, NULL));
rgrover1 252:d4e0cf5e8751 165 }
rgrover1 252:d4e0cf5e8751 166 }
rgrover1 252:d4e0cf5e8751 167
rgrover1 244:a966506d1e5b 168 void bleGattcEventHandler(const ble_evt_t *p_ble_evt)
rgrover1 244:a966506d1e5b 169 {
rgrover1 244:a966506d1e5b 170 switch (p_ble_evt->header.evt_id) {
rgrover1 244:a966506d1e5b 171 case BLE_GATTC_EVT_PRIM_SRVC_DISC_RSP:
rgrover1 244:a966506d1e5b 172 switch (p_ble_evt->evt.gattc_evt.gatt_status) {
rgrover1 244:a966506d1e5b 173 case BLE_GATT_STATUS_SUCCESS:
rgrover1 244:a966506d1e5b 174 discoverySingleton.setupDiscoveredServices(&p_ble_evt->evt.gattc_evt.params.prim_srvc_disc_rsp);
rgrover1 244:a966506d1e5b 175 break;
rgrover1 244:a966506d1e5b 176
rgrover1 244:a966506d1e5b 177 case BLE_GATT_STATUS_ATTERR_ATTRIBUTE_NOT_FOUND:
rgrover1 244:a966506d1e5b 178 default:
rgrover1 244:a966506d1e5b 179 discoverySingleton.terminate();
rgrover1 244:a966506d1e5b 180 break;
rgrover1 244:a966506d1e5b 181 }
rgrover1 244:a966506d1e5b 182 break;
rgrover1 244:a966506d1e5b 183
rgrover1 244:a966506d1e5b 184 case BLE_GATTC_EVT_CHAR_DISC_RSP:
rgrover1 244:a966506d1e5b 185 switch (p_ble_evt->evt.gattc_evt.gatt_status) {
rgrover1 244:a966506d1e5b 186 case BLE_GATT_STATUS_SUCCESS:
rgrover1 244:a966506d1e5b 187 discoverySingleton.setupDiscoveredCharacteristics(&p_ble_evt->evt.gattc_evt.params.char_disc_rsp);
rgrover1 244:a966506d1e5b 188 break;
rgrover1 244:a966506d1e5b 189
rgrover1 244:a966506d1e5b 190 case BLE_GATT_STATUS_ATTERR_ATTRIBUTE_NOT_FOUND:
rgrover1 244:a966506d1e5b 191 default:
rgrover1 244:a966506d1e5b 192 discoverySingleton.terminateCharacteristicDiscovery();
rgrover1 244:a966506d1e5b 193 break;
rgrover1 244:a966506d1e5b 194 }
rgrover1 244:a966506d1e5b 195 break;
rgrover1 244:a966506d1e5b 196 }
rgrover1 244:a966506d1e5b 197
rgrover1 244:a966506d1e5b 198 discoverySingleton.progressCharacteristicDiscovery();
rgrover1 244:a966506d1e5b 199 discoverySingleton.progressServiceDiscovery();
rgrover1 240:693a1f145b5a 200 }