Shuta Nakamae / nRF51822

Fork of nRF51822 by Nordic Semiconductor

Committer:
rgrover1
Date:
Fri Jun 19 15:55:19 2015 +0100
Revision:
226:416f90600fbe
Parent:
225:08f36b78e0f1
Child:
227:7a0bb8545c75
Synchronized with git rev 7be2b555
Author: Rohit Grover
no need for constructor for DiscoveredService/Characteristic

Who changed what in which revision?

UserRevisionLine numberNew contents of line
rgrover1 194:c99fc3160091 1 /* mbed Microcontroller Library
rgrover1 194:c99fc3160091 2 * Copyright (c) 2006-2013 ARM Limited
rgrover1 194:c99fc3160091 3 *
rgrover1 194:c99fc3160091 4 * Licensed under the Apache License, Version 2.0 (the "License");
rgrover1 194:c99fc3160091 5 * you may not use this file except in compliance with the License.
rgrover1 194:c99fc3160091 6 * You may obtain a copy of the License at
rgrover1 194:c99fc3160091 7 *
rgrover1 194:c99fc3160091 8 * http://www.apache.org/licenses/LICENSE-2.0
rgrover1 194:c99fc3160091 9 *
rgrover1 194:c99fc3160091 10 * Unless required by applicable law or agreed to in writing, software
rgrover1 194:c99fc3160091 11 * distributed under the License is distributed on an "AS IS" BASIS,
rgrover1 194:c99fc3160091 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
rgrover1 194:c99fc3160091 13 * See the License for the specific language governing permissions and
rgrover1 194:c99fc3160091 14 * limitations under the License.
rgrover1 194:c99fc3160091 15 */
rgrover1 194:c99fc3160091 16
rgrover1 194:c99fc3160091 17 #include "btle_gattc.h"
rgrover1 195:061ed80ffbcf 18 #include "UUID.h"
rgrover1 194:c99fc3160091 19
rgrover1 194:c99fc3160091 20 #define BLE_DB_DISCOVERY_MAX_SRV 4 /**< Maximum number of services supported by this module. This also indicates the maximum number of users allowed to be registered to this module. (one user per service). */
rgrover1 194:c99fc3160091 21 #define BLE_DB_DISCOVERY_MAX_CHAR_PER_SRV 4 /**< Maximum number of characteristics per service supported by this module. */
rgrover1 194:c99fc3160091 22
rgrover1 194:c99fc3160091 23 #define SRV_DISC_START_HANDLE 0x0001 /**< The start handle value used during service discovery. */
rgrover1 194:c99fc3160091 24
rgrover1 194:c99fc3160091 25
rgrover1 221:61527a178b9a 26 void launchServiceDiscovery(Gap::Handle_t connectionHandle);
rgrover1 221:61527a178b9a 27 void launchCharacteristicDiscovery(Gap::Handle_t connectionHandle, Gap::Handle_t startHandle, Gap::Handle_t endHandle);
rgrover1 221:61527a178b9a 28
rgrover1 221:61527a178b9a 29
rgrover1 194:c99fc3160091 30 /**@brief Structure for holding information about the service and the characteristics found during
rgrover1 194:c99fc3160091 31 * the discovery process.
rgrover1 194:c99fc3160091 32 */
rgrover1 195:061ed80ffbcf 33 struct DiscoveredService {
rgrover1 195:061ed80ffbcf 34 void setup(ShortUUIDBytes_t uuidIn, Gap::Handle_t start, Gap::Handle_t end) {
rgrover1 195:061ed80ffbcf 35 uuid = uuidIn;
rgrover1 195:061ed80ffbcf 36 startHandle = start;
rgrover1 195:061ed80ffbcf 37 endHandle = end;
rgrover1 195:061ed80ffbcf 38 }
rgrover1 201:a13ada00eac7 39
rgrover1 208:12b6b06ffcd6 40 ShortUUIDBytes_t uuid; /**< UUID of the service. */
rgrover1 208:12b6b06ffcd6 41 Gap::Handle_t startHandle; /**< Service Handle Range. */
rgrover1 208:12b6b06ffcd6 42 Gap::Handle_t endHandle; /**< Service Handle Range. */
rgrover1 195:061ed80ffbcf 43 };
rgrover1 194:c99fc3160091 44
rgrover1 210:e7749aec4203 45 /**@brief Structure for holding information about the service and the characteristics found during
rgrover1 210:e7749aec4203 46 * the discovery process.
rgrover1 210:e7749aec4203 47 */
rgrover1 210:e7749aec4203 48 struct DiscoveredCharacteristic {
rgrover1 215:36f6796651ab 49 void setup(ShortUUIDBytes_t uuidIn, ble_gatt_char_props_t propsIn, Gap::Handle_t declHandleIn, Gap::Handle_t valueHandleIn) {
rgrover1 210:e7749aec4203 50 uuid = uuidIn;
rgrover1 215:36f6796651ab 51 props = propsIn;
rgrover1 215:36f6796651ab 52 declHandle = declHandleIn;
rgrover1 215:36f6796651ab 53 valueHandle = valueHandleIn;
rgrover1 210:e7749aec4203 54 }
rgrover1 210:e7749aec4203 55
rgrover1 215:36f6796651ab 56 ShortUUIDBytes_t uuid;
rgrover1 215:36f6796651ab 57 ble_gatt_char_props_t props;
rgrover1 215:36f6796651ab 58 Gap::Handle_t declHandle; /**< Service Handle Range. */
rgrover1 215:36f6796651ab 59 Gap::Handle_t valueHandle; /**< Service Handle Range. */
rgrover1 210:e7749aec4203 60 };
rgrover1 210:e7749aec4203 61
rgrover1 222:0ba395e1303d 62 struct DiscoveryStatus {
rgrover1 214:196183e51de3 63 void terminateServiceDiscovery(void) {
rgrover1 214:196183e51de3 64 serviceDiscoveryInProgress = false;
rgrover1 214:196183e51de3 65 printf("end of service discovery\r\n");
rgrover1 214:196183e51de3 66 }
rgrover1 214:196183e51de3 67
rgrover1 214:196183e51de3 68 void terminateCharacteristicDiscovery(void) {
rgrover1 214:196183e51de3 69 characteristicDiscoveryInProgress = false;
rgrover1 214:196183e51de3 70 serviceDiscoveryInProgress = true;
rgrover1 217:c57cbfdfb5ca 71 currSrvInd++; /* Progress service index to keep discovery alive. */
rgrover1 214:196183e51de3 72 }
rgrover1 214:196183e51de3 73
rgrover1 214:196183e51de3 74 void resetDiscoveredServices(void) {
rgrover1 214:196183e51de3 75 memset(services, 0, sizeof(DiscoveredService) * BLE_DB_DISCOVERY_MAX_SRV);
rgrover1 214:196183e51de3 76 }
rgrover1 214:196183e51de3 77
rgrover1 214:196183e51de3 78 void serviceDiscoveryStarted(Gap::Handle_t connectionHandle) {
rgrover1 214:196183e51de3 79 connHandle = connectionHandle;
rgrover1 214:196183e51de3 80 srvCount = 0;
rgrover1 214:196183e51de3 81 currSrvInd = 0;
rgrover1 214:196183e51de3 82 serviceDiscoveryInProgress = true;
rgrover1 214:196183e51de3 83 characteristicDiscoveryInProgress = false;
rgrover1 214:196183e51de3 84 }
rgrover1 214:196183e51de3 85
rgrover1 214:196183e51de3 86 void characteristicDiscoveryStarted(Gap::Handle_t connectionHandle) {
rgrover1 214:196183e51de3 87 connHandle = connectionHandle;
rgrover1 214:196183e51de3 88 charCount = 0;
rgrover1 214:196183e51de3 89 currCharInd = 0;
rgrover1 214:196183e51de3 90 characteristicDiscoveryInProgress = true;
rgrover1 214:196183e51de3 91 serviceDiscoveryInProgress = false;
rgrover1 214:196183e51de3 92 }
rgrover1 214:196183e51de3 93
rgrover1 225:08f36b78e0f1 94 void setupDiscoveredServices(const ble_gattc_evt_prim_srvc_disc_rsp_t *response) {
rgrover1 225:08f36b78e0f1 95 currSrvInd = 0;
rgrover1 225:08f36b78e0f1 96 srvCount = response->count;
rgrover1 225:08f36b78e0f1 97
rgrover1 225:08f36b78e0f1 98 for (unsigned serviceIndex = 0; serviceIndex < srvCount; serviceIndex++) {
rgrover1 225:08f36b78e0f1 99 services[serviceIndex].setup(response->services[serviceIndex].uuid.uuid,
rgrover1 225:08f36b78e0f1 100 response->services[serviceIndex].handle_range.start_handle,
rgrover1 225:08f36b78e0f1 101 response->services[serviceIndex].handle_range.end_handle);
rgrover1 225:08f36b78e0f1 102 }
rgrover1 225:08f36b78e0f1 103 }
rgrover1 225:08f36b78e0f1 104
rgrover1 225:08f36b78e0f1 105 void setupDiscoveredCharacteristics(const ble_gattc_evt_char_disc_rsp_t *response) {
rgrover1 225:08f36b78e0f1 106 currCharInd = 0;
rgrover1 225:08f36b78e0f1 107 charCount = response->count;
rgrover1 225:08f36b78e0f1 108
rgrover1 225:08f36b78e0f1 109 for (unsigned charIndex = 0; charIndex < charCount; charIndex++) {
rgrover1 225:08f36b78e0f1 110 characteristics[charIndex].setup(response->chars[charIndex].uuid.uuid,
rgrover1 225:08f36b78e0f1 111 response->chars[charIndex].char_props,
rgrover1 225:08f36b78e0f1 112 response->chars[charIndex].handle_decl,
rgrover1 225:08f36b78e0f1 113 response->chars[charIndex].handle_value);
rgrover1 225:08f36b78e0f1 114 }
rgrover1 225:08f36b78e0f1 115 }
rgrover1 225:08f36b78e0f1 116
rgrover1 223:cfa98ce48348 117 void progressCharacteristicDiscovery() {
rgrover1 223:cfa98ce48348 118 while (characteristicDiscoveryInProgress && (currCharInd < charCount)) {
rgrover1 223:cfa98ce48348 119 printf("%x [%u]\r\n",
rgrover1 223:cfa98ce48348 120 characteristics[currCharInd].uuid,
rgrover1 223:cfa98ce48348 121 characteristics[currCharInd].valueHandle);
rgrover1 223:cfa98ce48348 122 currCharInd++;
rgrover1 223:cfa98ce48348 123 }
rgrover1 223:cfa98ce48348 124
rgrover1 223:cfa98ce48348 125 if (characteristicDiscoveryInProgress) {
rgrover1 223:cfa98ce48348 126 Gap::Handle_t startHandle = characteristics[currCharInd - 1].valueHandle + 1;
rgrover1 223:cfa98ce48348 127 Gap::Handle_t endHandle = services[currSrvInd].endHandle;
rgrover1 223:cfa98ce48348 128
rgrover1 223:cfa98ce48348 129 if (startHandle < endHandle) {
rgrover1 223:cfa98ce48348 130 ble_gattc_handle_range_t handleRange = {
rgrover1 223:cfa98ce48348 131 .start_handle = startHandle,
rgrover1 223:cfa98ce48348 132 .end_handle = endHandle
rgrover1 223:cfa98ce48348 133 };
rgrover1 223:cfa98ce48348 134 printf("char discovery returned %u\r\n", sd_ble_gattc_characteristics_discover(connHandle, &handleRange));
rgrover1 223:cfa98ce48348 135 } else {
rgrover1 223:cfa98ce48348 136 terminateCharacteristicDiscovery();
rgrover1 223:cfa98ce48348 137 }
rgrover1 223:cfa98ce48348 138 }
rgrover1 223:cfa98ce48348 139 }
rgrover1 223:cfa98ce48348 140
rgrover1 223:cfa98ce48348 141 void progressServiceDiscovery() {
rgrover1 223:cfa98ce48348 142 while (serviceDiscoveryInProgress && (currSrvInd < srvCount)) {
rgrover1 223:cfa98ce48348 143 printf("%x [%u %u]\r\n",
rgrover1 223:cfa98ce48348 144 services[currSrvInd].uuid,
rgrover1 223:cfa98ce48348 145 services[currSrvInd].startHandle,
rgrover1 223:cfa98ce48348 146 services[currSrvInd].endHandle);
rgrover1 223:cfa98ce48348 147
rgrover1 223:cfa98ce48348 148 launchCharacteristicDiscovery(connHandle, services[currSrvInd].startHandle, services[currSrvInd].endHandle);
rgrover1 223:cfa98ce48348 149 }
rgrover1 223:cfa98ce48348 150 if (serviceDiscoveryInProgress && (srvCount > 0) && (currSrvInd > 0)) {
rgrover1 223:cfa98ce48348 151 Gap::Handle_t endHandle = services[currSrvInd - 1].endHandle;
rgrover1 223:cfa98ce48348 152 resetDiscoveredServices();
rgrover1 223:cfa98ce48348 153 printf("services discover returned %u\r\n",
rgrover1 223:cfa98ce48348 154 sd_ble_gattc_primary_services_discover(connHandle, endHandle, NULL));
rgrover1 223:cfa98ce48348 155 }
rgrover1 223:cfa98ce48348 156 }
rgrover1 223:cfa98ce48348 157
rgrover1 216:3443c78324b6 158 DiscoveredService services[BLE_DB_DISCOVERY_MAX_SRV]; /**< Information related to the current service being discovered.
rgrover1 216:3443c78324b6 159 * This is intended for internal use during service discovery. */
rgrover1 216:3443c78324b6 160 DiscoveredCharacteristic characteristics[BLE_DB_DISCOVERY_MAX_CHAR_PER_SRV];
rgrover1 205:7b1c55e70f45 161
rgrover1 206:d8c5b97557f2 162 uint16_t connHandle; /**< Connection handle as provided by the SoftDevice. */
rgrover1 209:d24159a1dad5 163 uint8_t currSrvInd; /**< Index of the current service being discovered. This is intended for internal use during service discovery.*/
rgrover1 206:d8c5b97557f2 164 uint8_t srvCount; /**< Number of services at the peers GATT database.*/
rgrover1 206:d8c5b97557f2 165 uint8_t currCharInd; /**< Index of the current characteristic being discovered. This is intended for internal use during service discovery.*/
rgrover1 209:d24159a1dad5 166 uint8_t charCount; /**< Number of characteristics within the service.*/
rgrover1 206:d8c5b97557f2 167
rgrover1 206:d8c5b97557f2 168 bool serviceDiscoveryInProgress;
rgrover1 206:d8c5b97557f2 169 bool characteristicDiscoveryInProgress;
rgrover1 198:a69d3d4797e8 170 };
rgrover1 194:c99fc3160091 171
rgrover1 222:0ba395e1303d 172 static DiscoveryStatus discoveryStatus;
rgrover1 195:061ed80ffbcf 173
rgrover1 194:c99fc3160091 174 void launchServiceDiscovery(Gap::Handle_t connectionHandle)
rgrover1 194:c99fc3160091 175 {
rgrover1 214:196183e51de3 176 discoveryStatus.serviceDiscoveryStarted(connectionHandle);
rgrover1 194:c99fc3160091 177 printf("launch service discovery returned %u\r\n", sd_ble_gattc_primary_services_discover(connectionHandle, SRV_DISC_START_HANDLE, NULL));
rgrover1 194:c99fc3160091 178 }
rgrover1 194:c99fc3160091 179
rgrover1 202:3ce954ce3eb8 180 void launchCharacteristicDiscovery(Gap::Handle_t connectionHandle, Gap::Handle_t startHandle, Gap::Handle_t endHandle) {
rgrover1 214:196183e51de3 181 discoveryStatus.characteristicDiscoveryStarted(connectionHandle);
rgrover1 211:bf81b20ede23 182
rgrover1 211:bf81b20ede23 183 ble_gattc_handle_range_t handleRange = {
rgrover1 211:bf81b20ede23 184 .start_handle = startHandle,
rgrover1 211:bf81b20ede23 185 .end_handle = endHandle
rgrover1 211:bf81b20ede23 186 };
rgrover1 211:bf81b20ede23 187 printf("launch characteristic discovery returned %u\r\n", sd_ble_gattc_characteristics_discover(connectionHandle, &handleRange));
rgrover1 202:3ce954ce3eb8 188 }
rgrover1 202:3ce954ce3eb8 189
rgrover1 194:c99fc3160091 190 void bleGattcEventHandler(const ble_evt_t *p_ble_evt)
rgrover1 194:c99fc3160091 191 {
rgrover1 194:c99fc3160091 192 switch (p_ble_evt->header.evt_id) {
rgrover1 194:c99fc3160091 193 case BLE_GATTC_EVT_PRIM_SRVC_DISC_RSP:
rgrover1 194:c99fc3160091 194 switch (p_ble_evt->evt.gattc_evt.gatt_status) {
rgrover1 194:c99fc3160091 195 case BLE_GATT_STATUS_SUCCESS: {
rgrover1 225:08f36b78e0f1 196 discoveryStatus.setupDiscoveredServices(&p_ble_evt->evt.gattc_evt.params.prim_srvc_disc_rsp);
rgrover1 195:061ed80ffbcf 197 break;
rgrover1 194:c99fc3160091 198 }
rgrover1 195:061ed80ffbcf 199
rgrover1 194:c99fc3160091 200 case BLE_GATT_STATUS_ATTERR_ATTRIBUTE_NOT_FOUND: {
rgrover1 214:196183e51de3 201 discoveryStatus.terminateServiceDiscovery();
rgrover1 194:c99fc3160091 202 break;
rgrover1 194:c99fc3160091 203 }
rgrover1 195:061ed80ffbcf 204
rgrover1 194:c99fc3160091 205 default: {
rgrover1 197:de757ae3358b 206 discoveryStatus.serviceDiscoveryInProgress = false;
rgrover1 194:c99fc3160091 207 printf("gatt failure status: %u\r\n", p_ble_evt->evt.gattc_evt.gatt_status);
rgrover1 194:c99fc3160091 208 break;
rgrover1 194:c99fc3160091 209 }
rgrover1 194:c99fc3160091 210 }
rgrover1 194:c99fc3160091 211 break;
rgrover1 194:c99fc3160091 212
rgrover1 194:c99fc3160091 213 case BLE_GATTC_EVT_CHAR_DISC_RSP: {
rgrover1 194:c99fc3160091 214 switch (p_ble_evt->evt.gattc_evt.gatt_status) {
rgrover1 212:f2316b17d8be 215 case BLE_GATT_STATUS_SUCCESS: {
rgrover1 225:08f36b78e0f1 216 discoveryStatus.setupDiscoveredCharacteristics(&p_ble_evt->evt.gattc_evt.params.char_disc_rsp);
rgrover1 219:681be3608738 217 break;
rgrover1 212:f2316b17d8be 218 }
rgrover1 212:f2316b17d8be 219
rgrover1 212:f2316b17d8be 220 case BLE_GATT_STATUS_ATTERR_ATTRIBUTE_NOT_FOUND: {
rgrover1 214:196183e51de3 221 discoveryStatus.terminateCharacteristicDiscovery();
rgrover1 212:f2316b17d8be 222 break;
rgrover1 212:f2316b17d8be 223 }
rgrover1 212:f2316b17d8be 224
rgrover1 194:c99fc3160091 225 default:
rgrover1 212:f2316b17d8be 226 printf("char response: gatt failure status: %u\r\n", p_ble_evt->evt.gattc_evt.gatt_status);
rgrover1 194:c99fc3160091 227 break;
rgrover1 194:c99fc3160091 228 }
rgrover1 194:c99fc3160091 229 break;
rgrover1 194:c99fc3160091 230 }
rgrover1 194:c99fc3160091 231 }
rgrover1 195:061ed80ffbcf 232
rgrover1 223:cfa98ce48348 233 discoveryStatus.progressCharacteristicDiscovery();
rgrover1 223:cfa98ce48348 234 discoveryStatus.progressServiceDiscovery();
rgrover1 194:c99fc3160091 235 }