Shuta Nakamae / nRF51822

Fork of nRF51822 by Nordic Semiconductor

Committer:
rgrover1
Date:
Fri Jun 19 15:55:19 2015 +0100
Revision:
221:61527a178b9a
Parent:
220:ee888228a03e
Child:
222:0ba395e1303d
Synchronized with git rev 27e204ab
Author: Rohit Grover
add forward declarations for launch*()

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 DiscoveredService() {
rgrover1 195:061ed80ffbcf 35 /* empty */
rgrover1 195:061ed80ffbcf 36 }
rgrover1 195:061ed80ffbcf 37 DiscoveredService(ShortUUIDBytes_t uuidIn, Gap::Handle_t start, Gap::Handle_t end) {
rgrover1 195:061ed80ffbcf 38 setup(uuidIn, start, end);
rgrover1 195:061ed80ffbcf 39 }
rgrover1 195:061ed80ffbcf 40
rgrover1 195:061ed80ffbcf 41 void setup(ShortUUIDBytes_t uuidIn, Gap::Handle_t start, Gap::Handle_t end) {
rgrover1 195:061ed80ffbcf 42 uuid = uuidIn;
rgrover1 195:061ed80ffbcf 43 startHandle = start;
rgrover1 195:061ed80ffbcf 44 endHandle = end;
rgrover1 195:061ed80ffbcf 45 }
rgrover1 201:a13ada00eac7 46
rgrover1 208:12b6b06ffcd6 47 ShortUUIDBytes_t uuid; /**< UUID of the service. */
rgrover1 208:12b6b06ffcd6 48 Gap::Handle_t startHandle; /**< Service Handle Range. */
rgrover1 208:12b6b06ffcd6 49 Gap::Handle_t endHandle; /**< Service Handle Range. */
rgrover1 195:061ed80ffbcf 50 };
rgrover1 194:c99fc3160091 51
rgrover1 210:e7749aec4203 52 /**@brief Structure for holding information about the service and the characteristics found during
rgrover1 210:e7749aec4203 53 * the discovery process.
rgrover1 210:e7749aec4203 54 */
rgrover1 210:e7749aec4203 55 struct DiscoveredCharacteristic {
rgrover1 210:e7749aec4203 56 DiscoveredCharacteristic() {
rgrover1 210:e7749aec4203 57 /* empty */
rgrover1 210:e7749aec4203 58 }
rgrover1 215:36f6796651ab 59 DiscoveredCharacteristic(ShortUUIDBytes_t uuidIn, ble_gatt_char_props_t props, Gap::Handle_t declHandle, Gap::Handle_t valueHandle) {
rgrover1 215:36f6796651ab 60 setup(uuidIn, props, declHandle, valueHandle);
rgrover1 210:e7749aec4203 61 }
rgrover1 210:e7749aec4203 62
rgrover1 215:36f6796651ab 63 void setup(ShortUUIDBytes_t uuidIn, ble_gatt_char_props_t propsIn, Gap::Handle_t declHandleIn, Gap::Handle_t valueHandleIn) {
rgrover1 210:e7749aec4203 64 uuid = uuidIn;
rgrover1 215:36f6796651ab 65 props = propsIn;
rgrover1 215:36f6796651ab 66 declHandle = declHandleIn;
rgrover1 215:36f6796651ab 67 valueHandle = valueHandleIn;
rgrover1 210:e7749aec4203 68 }
rgrover1 210:e7749aec4203 69
rgrover1 215:36f6796651ab 70 ShortUUIDBytes_t uuid;
rgrover1 215:36f6796651ab 71 ble_gatt_char_props_t props;
rgrover1 215:36f6796651ab 72 Gap::Handle_t declHandle; /**< Service Handle Range. */
rgrover1 215:36f6796651ab 73 Gap::Handle_t valueHandle; /**< Service Handle Range. */
rgrover1 210:e7749aec4203 74 };
rgrover1 210:e7749aec4203 75
rgrover1 207:d70392d1af99 76 struct DiscoveryStatus_t {
rgrover1 214:196183e51de3 77 void terminateServiceDiscovery(void) {
rgrover1 214:196183e51de3 78 serviceDiscoveryInProgress = false;
rgrover1 214:196183e51de3 79 printf("end of service discovery\r\n");
rgrover1 214:196183e51de3 80 }
rgrover1 214:196183e51de3 81
rgrover1 214:196183e51de3 82 void terminateCharacteristicDiscovery(void) {
rgrover1 214:196183e51de3 83 characteristicDiscoveryInProgress = false;
rgrover1 214:196183e51de3 84 serviceDiscoveryInProgress = true;
rgrover1 217:c57cbfdfb5ca 85 currSrvInd++; /* Progress service index to keep discovery alive. */
rgrover1 214:196183e51de3 86 }
rgrover1 214:196183e51de3 87
rgrover1 214:196183e51de3 88 void resetDiscoveredServices(void) {
rgrover1 214:196183e51de3 89 memset(services, 0, sizeof(DiscoveredService) * BLE_DB_DISCOVERY_MAX_SRV);
rgrover1 214:196183e51de3 90 }
rgrover1 214:196183e51de3 91
rgrover1 214:196183e51de3 92 void serviceDiscoveryStarted(Gap::Handle_t connectionHandle) {
rgrover1 214:196183e51de3 93 connHandle = connectionHandle;
rgrover1 214:196183e51de3 94 srvCount = 0;
rgrover1 214:196183e51de3 95 currSrvInd = 0;
rgrover1 214:196183e51de3 96 serviceDiscoveryInProgress = true;
rgrover1 214:196183e51de3 97 characteristicDiscoveryInProgress = false;
rgrover1 214:196183e51de3 98 }
rgrover1 214:196183e51de3 99
rgrover1 214:196183e51de3 100 void characteristicDiscoveryStarted(Gap::Handle_t connectionHandle) {
rgrover1 214:196183e51de3 101 connHandle = connectionHandle;
rgrover1 214:196183e51de3 102 charCount = 0;
rgrover1 214:196183e51de3 103 currCharInd = 0;
rgrover1 214:196183e51de3 104 characteristicDiscoveryInProgress = true;
rgrover1 214:196183e51de3 105 serviceDiscoveryInProgress = false;
rgrover1 214:196183e51de3 106 }
rgrover1 214:196183e51de3 107
rgrover1 216:3443c78324b6 108 DiscoveredService services[BLE_DB_DISCOVERY_MAX_SRV]; /**< Information related to the current service being discovered.
rgrover1 216:3443c78324b6 109 * This is intended for internal use during service discovery. */
rgrover1 216:3443c78324b6 110 DiscoveredCharacteristic characteristics[BLE_DB_DISCOVERY_MAX_CHAR_PER_SRV];
rgrover1 205:7b1c55e70f45 111
rgrover1 206:d8c5b97557f2 112 uint16_t connHandle; /**< Connection handle as provided by the SoftDevice. */
rgrover1 209:d24159a1dad5 113 uint8_t currSrvInd; /**< Index of the current service being discovered. This is intended for internal use during service discovery.*/
rgrover1 206:d8c5b97557f2 114 uint8_t srvCount; /**< Number of services at the peers GATT database.*/
rgrover1 206:d8c5b97557f2 115 uint8_t currCharInd; /**< Index of the current characteristic being discovered. This is intended for internal use during service discovery.*/
rgrover1 209:d24159a1dad5 116 uint8_t charCount; /**< Number of characteristics within the service.*/
rgrover1 206:d8c5b97557f2 117
rgrover1 206:d8c5b97557f2 118 bool serviceDiscoveryInProgress;
rgrover1 206:d8c5b97557f2 119 bool characteristicDiscoveryInProgress;
rgrover1 198:a69d3d4797e8 120 };
rgrover1 194:c99fc3160091 121
rgrover1 207:d70392d1af99 122 static DiscoveryStatus_t discoveryStatus;
rgrover1 195:061ed80ffbcf 123
rgrover1 194:c99fc3160091 124 void launchServiceDiscovery(Gap::Handle_t connectionHandle)
rgrover1 194:c99fc3160091 125 {
rgrover1 214:196183e51de3 126 discoveryStatus.serviceDiscoveryStarted(connectionHandle);
rgrover1 194:c99fc3160091 127 printf("launch service discovery returned %u\r\n", sd_ble_gattc_primary_services_discover(connectionHandle, SRV_DISC_START_HANDLE, NULL));
rgrover1 194:c99fc3160091 128 }
rgrover1 194:c99fc3160091 129
rgrover1 202:3ce954ce3eb8 130 void launchCharacteristicDiscovery(Gap::Handle_t connectionHandle, Gap::Handle_t startHandle, Gap::Handle_t endHandle) {
rgrover1 214:196183e51de3 131 discoveryStatus.characteristicDiscoveryStarted(connectionHandle);
rgrover1 211:bf81b20ede23 132
rgrover1 211:bf81b20ede23 133 ble_gattc_handle_range_t handleRange = {
rgrover1 211:bf81b20ede23 134 .start_handle = startHandle,
rgrover1 211:bf81b20ede23 135 .end_handle = endHandle
rgrover1 211:bf81b20ede23 136 };
rgrover1 211:bf81b20ede23 137 printf("launch characteristic discovery returned %u\r\n", sd_ble_gattc_characteristics_discover(connectionHandle, &handleRange));
rgrover1 202:3ce954ce3eb8 138 }
rgrover1 202:3ce954ce3eb8 139
rgrover1 194:c99fc3160091 140 void bleGattcEventHandler(const ble_evt_t *p_ble_evt)
rgrover1 194:c99fc3160091 141 {
rgrover1 194:c99fc3160091 142 switch (p_ble_evt->header.evt_id) {
rgrover1 194:c99fc3160091 143 case BLE_GATTC_EVT_PRIM_SRVC_DISC_RSP:
rgrover1 194:c99fc3160091 144 switch (p_ble_evt->evt.gattc_evt.gatt_status) {
rgrover1 194:c99fc3160091 145 case BLE_GATT_STATUS_SUCCESS: {
rgrover1 194:c99fc3160091 146 printf("count of primary services: %u\r\n", p_ble_evt->evt.gattc_evt.params.prim_srvc_disc_rsp.count);
rgrover1 195:061ed80ffbcf 147 discoveryStatus.connHandle = p_ble_evt->evt.gattc_evt.conn_handle;
rgrover1 195:061ed80ffbcf 148 discoveryStatus.currSrvInd = 0;
rgrover1 195:061ed80ffbcf 149 discoveryStatus.srvCount = p_ble_evt->evt.gattc_evt.params.prim_srvc_disc_rsp.count;
rgrover1 194:c99fc3160091 150
rgrover1 195:061ed80ffbcf 151 for (unsigned serviceIndex = 0; serviceIndex < discoveryStatus.srvCount; serviceIndex++) {
rgrover1 195:061ed80ffbcf 152 discoveryStatus.services[serviceIndex].
rgrover1 195:061ed80ffbcf 153 setup(p_ble_evt->evt.gattc_evt.params.prim_srvc_disc_rsp.services[serviceIndex].uuid.uuid,
rgrover1 195:061ed80ffbcf 154 p_ble_evt->evt.gattc_evt.params.prim_srvc_disc_rsp.services[serviceIndex].handle_range.start_handle,
rgrover1 195:061ed80ffbcf 155 p_ble_evt->evt.gattc_evt.params.prim_srvc_disc_rsp.services[serviceIndex].handle_range.end_handle);
rgrover1 194:c99fc3160091 156 }
rgrover1 195:061ed80ffbcf 157 break;
rgrover1 194:c99fc3160091 158 }
rgrover1 195:061ed80ffbcf 159
rgrover1 194:c99fc3160091 160 case BLE_GATT_STATUS_ATTERR_ATTRIBUTE_NOT_FOUND: {
rgrover1 214:196183e51de3 161 discoveryStatus.terminateServiceDiscovery();
rgrover1 194:c99fc3160091 162 break;
rgrover1 194:c99fc3160091 163 }
rgrover1 195:061ed80ffbcf 164
rgrover1 194:c99fc3160091 165 default: {
rgrover1 197:de757ae3358b 166 discoveryStatus.serviceDiscoveryInProgress = false;
rgrover1 194:c99fc3160091 167 printf("gatt failure status: %u\r\n", p_ble_evt->evt.gattc_evt.gatt_status);
rgrover1 194:c99fc3160091 168 break;
rgrover1 194:c99fc3160091 169 }
rgrover1 194:c99fc3160091 170 }
rgrover1 194:c99fc3160091 171 break;
rgrover1 194:c99fc3160091 172
rgrover1 194:c99fc3160091 173 case BLE_GATTC_EVT_CHAR_DISC_RSP: {
rgrover1 194:c99fc3160091 174 switch (p_ble_evt->evt.gattc_evt.gatt_status) {
rgrover1 212:f2316b17d8be 175 case BLE_GATT_STATUS_SUCCESS: {
rgrover1 212:f2316b17d8be 176 // printf("count of characteristics: %u\r\n", p_ble_evt->evt.gattc_evt.params.char_disc_rsp.count);
rgrover1 212:f2316b17d8be 177 discoveryStatus.currCharInd = 0;
rgrover1 212:f2316b17d8be 178 discoveryStatus.charCount = p_ble_evt->evt.gattc_evt.params.char_disc_rsp.count;
rgrover1 212:f2316b17d8be 179
rgrover1 212:f2316b17d8be 180 unsigned charIndex = 0;
rgrover1 212:f2316b17d8be 181 for (; charIndex < discoveryStatus.charCount; charIndex++) {
rgrover1 218:6812c045735a 182 discoveryStatus.characteristics[charIndex].
rgrover1 218:6812c045735a 183 setup(p_ble_evt->evt.gattc_evt.params.char_disc_rsp.chars[charIndex].uuid.uuid,
rgrover1 218:6812c045735a 184 p_ble_evt->evt.gattc_evt.params.char_disc_rsp.chars[charIndex].char_props,
rgrover1 218:6812c045735a 185 p_ble_evt->evt.gattc_evt.params.char_disc_rsp.chars[charIndex].handle_decl,
rgrover1 218:6812c045735a 186 p_ble_evt->evt.gattc_evt.params.char_disc_rsp.chars[charIndex].handle_value);
rgrover1 212:f2316b17d8be 187 }
rgrover1 219:681be3608738 188 break;
rgrover1 212:f2316b17d8be 189 }
rgrover1 212:f2316b17d8be 190
rgrover1 212:f2316b17d8be 191 case BLE_GATT_STATUS_ATTERR_ATTRIBUTE_NOT_FOUND: {
rgrover1 214:196183e51de3 192 discoveryStatus.terminateCharacteristicDiscovery();
rgrover1 212:f2316b17d8be 193 break;
rgrover1 212:f2316b17d8be 194 }
rgrover1 212:f2316b17d8be 195
rgrover1 194:c99fc3160091 196 default:
rgrover1 212:f2316b17d8be 197 printf("char response: gatt failure status: %u\r\n", p_ble_evt->evt.gattc_evt.gatt_status);
rgrover1 194:c99fc3160091 198 break;
rgrover1 194:c99fc3160091 199 }
rgrover1 194:c99fc3160091 200 break;
rgrover1 194:c99fc3160091 201 }
rgrover1 194:c99fc3160091 202 }
rgrover1 195:061ed80ffbcf 203
rgrover1 219:681be3608738 204 while (discoveryStatus.characteristicDiscoveryInProgress && (discoveryStatus.currCharInd < discoveryStatus.charCount)) {
rgrover1 219:681be3608738 205 printf("%x [%u]\r\n",
rgrover1 219:681be3608738 206 discoveryStatus.characteristics[discoveryStatus.currCharInd].uuid,
rgrover1 219:681be3608738 207 discoveryStatus.characteristics[discoveryStatus.currCharInd].valueHandle);
rgrover1 219:681be3608738 208 discoveryStatus.currCharInd++;
rgrover1 219:681be3608738 209 }
rgrover1 219:681be3608738 210
rgrover1 219:681be3608738 211 if (discoveryStatus.characteristicDiscoveryInProgress) {
rgrover1 219:681be3608738 212 Gap::Handle_t startHandle = discoveryStatus.characteristics[discoveryStatus.currCharInd - 1].valueHandle + 1;
rgrover1 219:681be3608738 213 Gap::Handle_t endHandle = discoveryStatus.services[discoveryStatus.currSrvInd].endHandle;
rgrover1 219:681be3608738 214
rgrover1 219:681be3608738 215 if (startHandle < endHandle) {
rgrover1 219:681be3608738 216 ble_gattc_handle_range_t handleRange = {
rgrover1 219:681be3608738 217 .start_handle = startHandle,
rgrover1 219:681be3608738 218 .end_handle = endHandle
rgrover1 219:681be3608738 219 };
rgrover1 219:681be3608738 220 printf("char discovery returned %u\r\n", sd_ble_gattc_characteristics_discover(discoveryStatus.connHandle, &handleRange));
rgrover1 219:681be3608738 221 } else {
rgrover1 219:681be3608738 222 discoveryStatus.terminateCharacteristicDiscovery();
rgrover1 219:681be3608738 223 }
rgrover1 219:681be3608738 224 }
rgrover1 219:681be3608738 225
rgrover1 199:c2c831c55f3d 226 while (discoveryStatus.serviceDiscoveryInProgress && (discoveryStatus.currSrvInd < discoveryStatus.srvCount)) {
rgrover1 195:061ed80ffbcf 227 printf("%x [%u %u]\r\n",
rgrover1 212:f2316b17d8be 228 discoveryStatus.services[discoveryStatus.currSrvInd].uuid,
rgrover1 212:f2316b17d8be 229 discoveryStatus.services[discoveryStatus.currSrvInd].startHandle,
rgrover1 212:f2316b17d8be 230 discoveryStatus.services[discoveryStatus.currSrvInd].endHandle);
rgrover1 195:061ed80ffbcf 231
rgrover1 212:f2316b17d8be 232 launchCharacteristicDiscovery(discoveryStatus.connHandle,
rgrover1 212:f2316b17d8be 233 discoveryStatus.services[discoveryStatus.currSrvInd].startHandle,
rgrover1 212:f2316b17d8be 234 discoveryStatus.services[discoveryStatus.currSrvInd].endHandle);
rgrover1 195:061ed80ffbcf 235 }
rgrover1 212:f2316b17d8be 236 if (discoveryStatus.serviceDiscoveryInProgress && (discoveryStatus.srvCount > 0) && (discoveryStatus.currSrvInd > 0)) {
rgrover1 212:f2316b17d8be 237 Gap::Handle_t endHandle = discoveryStatus.services[discoveryStatus.currSrvInd - 1].endHandle;
rgrover1 214:196183e51de3 238 discoveryStatus.resetDiscoveredServices();
rgrover1 196:70f1b8354d57 239 printf("services discover returned %u\r\n",
rgrover1 212:f2316b17d8be 240 sd_ble_gattc_primary_services_discover(discoveryStatus.connHandle, endHandle, NULL));
rgrover1 196:70f1b8354d57 241 }
rgrover1 194:c99fc3160091 242 }