test

Fork of nRF51822 by Nordic Semiconductor

Committer:
rgrover1
Date:
Fri Jun 19 15:55:21 2015 +0100
Revision:
239:693a1f145b5a
Child:
240:75b69581d1dd
Synchronized with git rev 50a110cd
Author: Rohit Grover
partial separation of code related to discovery into files.

Who changed what in which revision?

UserRevisionLine numberNew contents of line
rgrover1 239:693a1f145b5a 1 /* mbed Microcontroller Library
rgrover1 239:693a1f145b5a 2 * Copyright (c) 2006-2013 ARM Limited
rgrover1 239:693a1f145b5a 3 *
rgrover1 239:693a1f145b5a 4 * Licensed under the Apache License, Version 2.0 (the "License");
rgrover1 239:693a1f145b5a 5 * you may not use this file except in compliance with the License.
rgrover1 239:693a1f145b5a 6 * You may obtain a copy of the License at
rgrover1 239:693a1f145b5a 7 *
rgrover1 239:693a1f145b5a 8 * http://www.apache.org/licenses/LICENSE-2.0
rgrover1 239:693a1f145b5a 9 *
rgrover1 239:693a1f145b5a 10 * Unless required by applicable law or agreed to in writing, software
rgrover1 239:693a1f145b5a 11 * distributed under the License is distributed on an "AS IS" BASIS,
rgrover1 239:693a1f145b5a 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
rgrover1 239:693a1f145b5a 13 * See the License for the specific language governing permissions and
rgrover1 239:693a1f145b5a 14 * limitations under the License.
rgrover1 239:693a1f145b5a 15 */
rgrover1 239:693a1f145b5a 16
rgrover1 239:693a1f145b5a 17 #ifndef _BTLE_DISCOVERY_H_
rgrover1 239:693a1f145b5a 18 #define _BTLE_DISCOVERY_H_
rgrover1 239:693a1f145b5a 19
rgrover1 239:693a1f145b5a 20 #include "blecommon.h"
rgrover1 239:693a1f145b5a 21 #include "UUID.h"
rgrover1 239:693a1f145b5a 22 #include "Gap.h"
rgrover1 239:693a1f145b5a 23 #include "ble_gattc.h"
rgrover1 239:693a1f145b5a 24 #include <stdio.h>
rgrover1 239:693a1f145b5a 25
rgrover1 239:693a1f145b5a 26 /**@brief Structure for holding information about the service and the characteristics found during
rgrover1 239:693a1f145b5a 27 * the discovery process.
rgrover1 239:693a1f145b5a 28 */
rgrover1 239:693a1f145b5a 29 struct DiscoveredService {
rgrover1 239:693a1f145b5a 30 void setup(ShortUUIDBytes_t uuidIn, Gap::Handle_t start, Gap::Handle_t end) {
rgrover1 239:693a1f145b5a 31 uuid = uuidIn;
rgrover1 239:693a1f145b5a 32 startHandle = start;
rgrover1 239:693a1f145b5a 33 endHandle = end;
rgrover1 239:693a1f145b5a 34 }
rgrover1 239:693a1f145b5a 35
rgrover1 239:693a1f145b5a 36 ShortUUIDBytes_t uuid; /**< UUID of the service. */
rgrover1 239:693a1f145b5a 37 Gap::Handle_t startHandle; /**< Service Handle Range. */
rgrover1 239:693a1f145b5a 38 Gap::Handle_t endHandle; /**< Service Handle Range. */
rgrover1 239:693a1f145b5a 39 };
rgrover1 239:693a1f145b5a 40
rgrover1 239:693a1f145b5a 41 /**@brief Structure for holding information about the service and the characteristics found during
rgrover1 239:693a1f145b5a 42 * the discovery process.
rgrover1 239:693a1f145b5a 43 */
rgrover1 239:693a1f145b5a 44 struct DiscoveredCharacteristic {
rgrover1 239:693a1f145b5a 45 struct Properties_t {
rgrover1 239:693a1f145b5a 46 static const uint8_t BROADCAST_PROPERTY_MASK = 0x01;
rgrover1 239:693a1f145b5a 47 static const uint8_t READ_PROPERTY_MASK = 0x02;
rgrover1 239:693a1f145b5a 48 static const uint8_t WRITE_WO_RESPONSE_PROPERTY_MASK = 0x04;
rgrover1 239:693a1f145b5a 49 static const uint8_t WRITE_PROPERTY_MASK = 0x08;
rgrover1 239:693a1f145b5a 50 static const uint8_t NOTIFY_PROPERTY_MASK = 0x10;
rgrover1 239:693a1f145b5a 51 static const uint8_t INDICATE_PROPERTY_MASK = 0x20;
rgrover1 239:693a1f145b5a 52 static const uint8_t AUTH_SIGNED_PROPERTY_MASK = 0x40;
rgrover1 239:693a1f145b5a 53
rgrover1 239:693a1f145b5a 54 Properties_t() : broadcast(0), read(0), write_wo_resp(0), write(0), notify(0), indicate(0), auth_signed_wr(0) {
rgrover1 239:693a1f145b5a 55 /* empty */
rgrover1 239:693a1f145b5a 56 }
rgrover1 239:693a1f145b5a 57
rgrover1 239:693a1f145b5a 58 Properties_t(uint8_t props) :
rgrover1 239:693a1f145b5a 59 broadcast(props & BROADCAST_PROPERTY_MASK),
rgrover1 239:693a1f145b5a 60 read(props & READ_PROPERTY_MASK),
rgrover1 239:693a1f145b5a 61 write_wo_resp(props & WRITE_WO_RESPONSE_PROPERTY_MASK),
rgrover1 239:693a1f145b5a 62 write(props & WRITE_PROPERTY_MASK),
rgrover1 239:693a1f145b5a 63 notify(props & NOTIFY_PROPERTY_MASK),
rgrover1 239:693a1f145b5a 64 indicate(props & INDICATE_PROPERTY_MASK),
rgrover1 239:693a1f145b5a 65 auth_signed_wr(props & AUTH_SIGNED_PROPERTY_MASK) {
rgrover1 239:693a1f145b5a 66 /* empty*/
rgrover1 239:693a1f145b5a 67 }
rgrover1 239:693a1f145b5a 68
rgrover1 239:693a1f145b5a 69 uint8_t broadcast :1; /**< Broadcasting of the value permitted. */
rgrover1 239:693a1f145b5a 70 uint8_t read :1; /**< Reading the value permitted. */
rgrover1 239:693a1f145b5a 71 uint8_t write_wo_resp :1; /**< Writing the value with Write Command permitted. */
rgrover1 239:693a1f145b5a 72 uint8_t write :1; /**< Writing the value with Write Request permitted. */
rgrover1 239:693a1f145b5a 73 uint8_t notify :1; /**< Notications of the value permitted. */
rgrover1 239:693a1f145b5a 74 uint8_t indicate :1; /**< Indications of the value permitted. */
rgrover1 239:693a1f145b5a 75 uint8_t auth_signed_wr :1; /**< Writing the value with Signed Write Command permitted. */
rgrover1 239:693a1f145b5a 76 };
rgrover1 239:693a1f145b5a 77
rgrover1 239:693a1f145b5a 78 void setup(ShortUUIDBytes_t uuidIn, Properties_t propsIn, Gap::Handle_t declHandleIn, Gap::Handle_t valueHandleIn) {
rgrover1 239:693a1f145b5a 79 uuid = uuidIn;
rgrover1 239:693a1f145b5a 80 props = propsIn;
rgrover1 239:693a1f145b5a 81 declHandle = declHandleIn;
rgrover1 239:693a1f145b5a 82 valueHandle = valueHandleIn;
rgrover1 239:693a1f145b5a 83 }
rgrover1 239:693a1f145b5a 84
rgrover1 239:693a1f145b5a 85 ShortUUIDBytes_t uuid;
rgrover1 239:693a1f145b5a 86 Properties_t props;
rgrover1 239:693a1f145b5a 87 Gap::Handle_t declHandle;
rgrover1 239:693a1f145b5a 88 Gap::Handle_t valueHandle;
rgrover1 239:693a1f145b5a 89 };
rgrover1 239:693a1f145b5a 90
rgrover1 239:693a1f145b5a 91 class ServiceDiscovery {
rgrover1 239:693a1f145b5a 92 public:
rgrover1 239:693a1f145b5a 93 static const unsigned 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 239:693a1f145b5a 94 static const unsigned BLE_DB_DISCOVERY_MAX_CHAR_PER_SRV = 4; /**< Maximum number of characteristics per service supported by this module. */
rgrover1 239:693a1f145b5a 95
rgrover1 239:693a1f145b5a 96 static const uint16_t SRV_DISC_START_HANDLE = 0x0001; /**< The start handle value used during service discovery. */
rgrover1 239:693a1f145b5a 97
rgrover1 239:693a1f145b5a 98 typedef void (*ServiceCallback_t)(void);
rgrover1 239:693a1f145b5a 99 typedef void (*CharacteristicCallback_t)(void);
rgrover1 239:693a1f145b5a 100
rgrover1 239:693a1f145b5a 101 public:
rgrover1 239:693a1f145b5a 102 static ble_error_t launch(Gap::Handle_t connectionHandle,
rgrover1 239:693a1f145b5a 103 ServiceCallback_t sc,
rgrover1 239:693a1f145b5a 104 CharacteristicCallback_t cc = NULL);
rgrover1 239:693a1f145b5a 105 static ble_error_t launch(Gap::Handle_t connectionHandle,
rgrover1 239:693a1f145b5a 106 UUID matchingServiceUUID,
rgrover1 239:693a1f145b5a 107 ServiceCallback_t sc,
rgrover1 239:693a1f145b5a 108 UUID matchingCharacteristicUUID = ShortUUIDBytes_t(BLE_UUID_UNKNOWN),
rgrover1 239:693a1f145b5a 109 CharacteristicCallback_t cc = NULL);
rgrover1 239:693a1f145b5a 110
rgrover1 239:693a1f145b5a 111 static ServiceDiscovery *getSingleton(void);
rgrover1 239:693a1f145b5a 112
rgrover1 239:693a1f145b5a 113 private:
rgrover1 239:693a1f145b5a 114 ble_error_t launchCharacteristicDiscovery(Gap::Handle_t connectionHandle, Gap::Handle_t startHandle, Gap::Handle_t endHandle);
rgrover1 239:693a1f145b5a 115
rgrover1 239:693a1f145b5a 116 public:
rgrover1 239:693a1f145b5a 117 void terminate(void) {
rgrover1 239:693a1f145b5a 118 serviceDiscoveryInProgress = false;
rgrover1 239:693a1f145b5a 119 printf("end of service discovery\r\n");
rgrover1 239:693a1f145b5a 120 }
rgrover1 239:693a1f145b5a 121
rgrover1 239:693a1f145b5a 122 void terminateCharacteristicDiscovery(void) {
rgrover1 239:693a1f145b5a 123 characteristicDiscoveryInProgress = false;
rgrover1 239:693a1f145b5a 124 serviceDiscoveryInProgress = true;
rgrover1 239:693a1f145b5a 125 currSrvInd++; /* Progress service index to keep discovery alive. */
rgrover1 239:693a1f145b5a 126 }
rgrover1 239:693a1f145b5a 127
rgrover1 239:693a1f145b5a 128 void resetDiscoveredServices(void) {
rgrover1 239:693a1f145b5a 129 srvCount = 0;
rgrover1 239:693a1f145b5a 130 currSrvInd = 0;
rgrover1 239:693a1f145b5a 131 memset(services, 0, sizeof(DiscoveredService) * BLE_DB_DISCOVERY_MAX_SRV);
rgrover1 239:693a1f145b5a 132 }
rgrover1 239:693a1f145b5a 133
rgrover1 239:693a1f145b5a 134 void resetDiscoveredCharacteristics(void) {
rgrover1 239:693a1f145b5a 135 charCount = 0;
rgrover1 239:693a1f145b5a 136 currCharInd = 0;
rgrover1 239:693a1f145b5a 137 memset(characteristics, 0, sizeof(DiscoveredCharacteristic) * BLE_DB_DISCOVERY_MAX_CHAR_PER_SRV);
rgrover1 239:693a1f145b5a 138 }
rgrover1 239:693a1f145b5a 139
rgrover1 239:693a1f145b5a 140 void setupDiscoveredServices(const ble_gattc_evt_prim_srvc_disc_rsp_t *response);
rgrover1 239:693a1f145b5a 141 void setupDiscoveredCharacteristics(const ble_gattc_evt_char_disc_rsp_t *response);
rgrover1 239:693a1f145b5a 142
rgrover1 239:693a1f145b5a 143 void progressCharacteristicDiscovery() {
rgrover1 239:693a1f145b5a 144 while (characteristicDiscoveryInProgress && (currCharInd < charCount)) {
rgrover1 239:693a1f145b5a 145 /* THIS IS WHERE THE CALLBACK WILL GO */
rgrover1 239:693a1f145b5a 146 printf("%x [%u]\r\n", characteristics[currCharInd].uuid, characteristics[currCharInd].valueHandle);
rgrover1 239:693a1f145b5a 147
rgrover1 239:693a1f145b5a 148 currCharInd++;
rgrover1 239:693a1f145b5a 149 }
rgrover1 239:693a1f145b5a 150
rgrover1 239:693a1f145b5a 151 if (characteristicDiscoveryInProgress) {
rgrover1 239:693a1f145b5a 152 Gap::Handle_t startHandle = characteristics[currCharInd - 1].valueHandle + 1;
rgrover1 239:693a1f145b5a 153 Gap::Handle_t endHandle = services[currSrvInd].endHandle;
rgrover1 239:693a1f145b5a 154 resetDiscoveredCharacteristics();
rgrover1 239:693a1f145b5a 155
rgrover1 239:693a1f145b5a 156 if (startHandle < endHandle) {
rgrover1 239:693a1f145b5a 157 ble_gattc_handle_range_t handleRange = {
rgrover1 239:693a1f145b5a 158 .start_handle = startHandle,
rgrover1 239:693a1f145b5a 159 .end_handle = endHandle
rgrover1 239:693a1f145b5a 160 };
rgrover1 239:693a1f145b5a 161 printf("char discovery returned %u\r\n", sd_ble_gattc_characteristics_discover(connHandle, &handleRange));
rgrover1 239:693a1f145b5a 162 } else {
rgrover1 239:693a1f145b5a 163 terminateCharacteristicDiscovery();
rgrover1 239:693a1f145b5a 164 }
rgrover1 239:693a1f145b5a 165 }
rgrover1 239:693a1f145b5a 166 }
rgrover1 239:693a1f145b5a 167
rgrover1 239:693a1f145b5a 168 void progressServiceDiscovery() {
rgrover1 239:693a1f145b5a 169 while (serviceDiscoveryInProgress && (currSrvInd < srvCount)) {
rgrover1 239:693a1f145b5a 170 /* THIS IS WHERE THE CALLBACK WILL GO */
rgrover1 239:693a1f145b5a 171 printf("%x [%u %u]\r\n", services[currSrvInd].uuid, services[currSrvInd].startHandle, services[currSrvInd].endHandle);
rgrover1 239:693a1f145b5a 172
rgrover1 239:693a1f145b5a 173 if (true) { /* characteristic discovery is optional. */
rgrover1 239:693a1f145b5a 174 launchCharacteristicDiscovery(connHandle, services[currSrvInd].startHandle, services[currSrvInd].endHandle);
rgrover1 239:693a1f145b5a 175 } else {
rgrover1 239:693a1f145b5a 176 currSrvInd++; /* Progress service index to keep discovery alive. */
rgrover1 239:693a1f145b5a 177 }
rgrover1 239:693a1f145b5a 178 }
rgrover1 239:693a1f145b5a 179 if (serviceDiscoveryInProgress && (srvCount > 0) && (currSrvInd > 0)) {
rgrover1 239:693a1f145b5a 180 Gap::Handle_t endHandle = services[currSrvInd - 1].endHandle;
rgrover1 239:693a1f145b5a 181 resetDiscoveredServices();
rgrover1 239:693a1f145b5a 182
rgrover1 239:693a1f145b5a 183 printf("services discover returned %u\r\n", sd_ble_gattc_primary_services_discover(connHandle, endHandle, NULL));
rgrover1 239:693a1f145b5a 184 }
rgrover1 239:693a1f145b5a 185 }
rgrover1 239:693a1f145b5a 186
rgrover1 239:693a1f145b5a 187 void serviceDiscoveryStarted(Gap::Handle_t connectionHandle) {
rgrover1 239:693a1f145b5a 188 connHandle = connectionHandle;
rgrover1 239:693a1f145b5a 189 resetDiscoveredServices();
rgrover1 239:693a1f145b5a 190 serviceDiscoveryInProgress = true;
rgrover1 239:693a1f145b5a 191 characteristicDiscoveryInProgress = false;
rgrover1 239:693a1f145b5a 192 }
rgrover1 239:693a1f145b5a 193
rgrover1 239:693a1f145b5a 194 private:
rgrover1 239:693a1f145b5a 195 void characteristicDiscoveryStarted(Gap::Handle_t connectionHandle) {
rgrover1 239:693a1f145b5a 196 connHandle = connectionHandle;
rgrover1 239:693a1f145b5a 197 resetDiscoveredCharacteristics();
rgrover1 239:693a1f145b5a 198 characteristicDiscoveryInProgress = true;
rgrover1 239:693a1f145b5a 199 serviceDiscoveryInProgress = false;
rgrover1 239:693a1f145b5a 200 }
rgrover1 239:693a1f145b5a 201
rgrover1 239:693a1f145b5a 202 private:
rgrover1 239:693a1f145b5a 203 ServiceDiscovery() {
rgrover1 239:693a1f145b5a 204 /* empty */
rgrover1 239:693a1f145b5a 205 }
rgrover1 239:693a1f145b5a 206
rgrover1 239:693a1f145b5a 207 public:
rgrover1 239:693a1f145b5a 208
rgrover1 239:693a1f145b5a 209 DiscoveredService services[BLE_DB_DISCOVERY_MAX_SRV]; /**< Information related to the current service being discovered.
rgrover1 239:693a1f145b5a 210 * This is intended for internal use during service discovery. */
rgrover1 239:693a1f145b5a 211 DiscoveredCharacteristic characteristics[BLE_DB_DISCOVERY_MAX_CHAR_PER_SRV];
rgrover1 239:693a1f145b5a 212
rgrover1 239:693a1f145b5a 213 uint16_t connHandle; /**< Connection handle as provided by the SoftDevice. */
rgrover1 239:693a1f145b5a 214 uint8_t currSrvInd; /**< Index of the current service being discovered. This is intended for internal use during service discovery.*/
rgrover1 239:693a1f145b5a 215 uint8_t srvCount; /**< Number of services at the peers GATT database.*/
rgrover1 239:693a1f145b5a 216 uint8_t currCharInd; /**< Index of the current characteristic being discovered. This is intended for internal use during service discovery.*/
rgrover1 239:693a1f145b5a 217 uint8_t charCount; /**< Number of characteristics within the service.*/
rgrover1 239:693a1f145b5a 218
rgrover1 239:693a1f145b5a 219 bool serviceDiscoveryInProgress;
rgrover1 239:693a1f145b5a 220 bool characteristicDiscoveryInProgress;
rgrover1 239:693a1f145b5a 221 };
rgrover1 239:693a1f145b5a 222
rgrover1 239:693a1f145b5a 223 #endif /*_BTLE_DISCOVERY_H_*/