Shuta Nakamae / nRF51822

Fork of nRF51822 by Nordic Semiconductor

Committer:
rgrover1
Date:
Fri Jun 19 15:55:18 2015 +0100
Revision:
212:f2316b17d8be
Parent:
211:bf81b20ede23
Child:
213:146636a106b1
Synchronized with git rev 1ffbf3e2
Author: Rohit Grover
initial working service discovery (with a lot of debugging printfs)

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