bluetooth control motor

Dependents:   BLE_LED_IDB0XA1_demo MOTOR_BLE_V2 Motor_Ble_v1 Motor_Ble_v10223 ... more

Fork of X_NUCLEO_IDB0XA1 by ST

Committer:
Andrea Palmieri
Date:
Mon May 16 17:22:03 2016 +0200
Revision:
229:9981f62cdb1a
Parent:
152:4afc5c2fc4f3
Child:
231:a0d2544b38cd
Fix issues and add features

- Fix handles management
- Fix UUIDs management
- Implement API to read random address
- Fix clearing/setting of ADV payload
- Fix scanning behaviour
- Fix scanning while a connection is ongoing
- Implement Char Descriptor discovery
- Implement scanning/advertising filter policy (White List partial management)
- Update underlying BlueNRG stack
- Cosmetics

Signed-off-by: Andrea Palmieri <andrea.palmieri@st.com>

Who changed what in which revision?

UserRevisionLine numberNew contents of line
Andrea Palmieri 229:9981f62cdb1a 1 /* mbed Microcontroller Library
Andrea Palmieri 229:9981f62cdb1a 2 * Copyright (c) 2006-2013 ARM Limited
Andrea Palmieri 229:9981f62cdb1a 3 *
Andrea Palmieri 229:9981f62cdb1a 4 * Licensed under the Apache License, Version 2.0 (the "License");
Andrea Palmieri 229:9981f62cdb1a 5 * you may not use this file except in compliance with the License.
Andrea Palmieri 229:9981f62cdb1a 6 * You may obtain a copy of the License at
Andrea Palmieri 229:9981f62cdb1a 7 *
Andrea Palmieri 229:9981f62cdb1a 8 * http://www.apache.org/licenses/LICENSE-2.0
Andrea Palmieri 229:9981f62cdb1a 9 *
Andrea Palmieri 229:9981f62cdb1a 10 * Unless required by applicable law or agreed to in writing, software
Andrea Palmieri 229:9981f62cdb1a 11 * distributed under the License is distributed on an "AS IS" BASIS,
Andrea Palmieri 229:9981f62cdb1a 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
Andrea Palmieri 229:9981f62cdb1a 13 * See the License for the specific language governing permissions and
Andrea Palmieri 229:9981f62cdb1a 14 * limitations under the License.
Andrea Palmieri 229:9981f62cdb1a 15 */
Andrea Palmieri 229:9981f62cdb1a 16 /**
Andrea Palmieri 229:9981f62cdb1a 17 ******************************************************************************
Andrea Palmieri 229:9981f62cdb1a 18 * @file BlueNRGGattServer.cpp
Andrea Palmieri 229:9981f62cdb1a 19 * @author STMicroelectronics
Andrea Palmieri 229:9981f62cdb1a 20 * @brief Implementation of BlueNRG BLE_API GattServer Class
Andrea Palmieri 229:9981f62cdb1a 21 ******************************************************************************
Andrea Palmieri 229:9981f62cdb1a 22 * @copy
Andrea Palmieri 229:9981f62cdb1a 23 *
Andrea Palmieri 229:9981f62cdb1a 24 * THE PRESENT FIRMWARE WHICH IS FOR GUIDANCE ONLY AIMS AT PROVIDING CUSTOMERS
Andrea Palmieri 229:9981f62cdb1a 25 * WITH CODING INFORMATION REGARDING THEIR PRODUCTS IN ORDER FOR THEM TO SAVE
Andrea Palmieri 229:9981f62cdb1a 26 * TIME. AS A RESULT, STMICROELECTRONICS SHALL NOT BE HELD LIABLE FOR ANY
Andrea Palmieri 229:9981f62cdb1a 27 * DIRECT, INDIRECT OR CONSEQUENTIAL DAMAGES WITH RESPECT TO ANY CLAIMS ARISING
Andrea Palmieri 229:9981f62cdb1a 28 * FROM THE CONTENT OF SUCH FIRMWARE AND/OR THE USE MADE BY CUSTOMERS OF THE
Andrea Palmieri 229:9981f62cdb1a 29 * CODING INFORMATION CONTAINED HEREIN IN CONNECTION WITH THEIR PRODUCTS.
Andrea Palmieri 229:9981f62cdb1a 30 *
Andrea Palmieri 229:9981f62cdb1a 31 * <h2><center>&copy; COPYRIGHT 2013 STMicroelectronics</center></h2>
Andrea Palmieri 229:9981f62cdb1a 32 */
Andrea Palmieri 229:9981f62cdb1a 33
Andrea Palmieri 229:9981f62cdb1a 34 /** @defgroup BlueNRGGATTClient
Andrea Palmieri 229:9981f62cdb1a 35 * @brief BlueNRG BLE_API GattClient Adaptation
Andrea Palmieri 229:9981f62cdb1a 36 * @{
Andrea Palmieri 229:9981f62cdb1a 37 */
Andrea Palmieri 229:9981f62cdb1a 38
Andrea Palmieri 229:9981f62cdb1a 39 #include "BlueNRGGattClient.h"
Andrea Palmieri 229:9981f62cdb1a 40 #include "mbed-drivers/mbed.h"
Andrea Palmieri 229:9981f62cdb1a 41 #include "BlueNRGGap.h"
Andrea Palmieri 229:9981f62cdb1a 42 #include "Utils.h"
Andrea Palmieri 229:9981f62cdb1a 43 #include "debug.h"
Andrea Palmieri 229:9981f62cdb1a 44
Andrea Palmieri 229:9981f62cdb1a 45 static uint8_t props_mask[] = {
Andrea Palmieri 229:9981f62cdb1a 46 0x01,
Andrea Palmieri 229:9981f62cdb1a 47 0x02,
Andrea Palmieri 229:9981f62cdb1a 48 0x04,
Andrea Palmieri 229:9981f62cdb1a 49 0x08,
Andrea Palmieri 229:9981f62cdb1a 50 0x10,
Andrea Palmieri 229:9981f62cdb1a 51 0x20,
Andrea Palmieri 229:9981f62cdb1a 52 0x40,
Andrea Palmieri 229:9981f62cdb1a 53 0x80
Andrea Palmieri 229:9981f62cdb1a 54 };
Andrea Palmieri 229:9981f62cdb1a 55
Andrea Palmieri 229:9981f62cdb1a 56 void BlueNRGGattClient::gattProcedureCompleteCB(Gap::Handle_t connectionHandle, uint8_t error_code)
Andrea Palmieri 229:9981f62cdb1a 57 {
Andrea Palmieri 229:9981f62cdb1a 58 if(error_code != BLE_STATUS_SUCCESS) {
Andrea Palmieri 229:9981f62cdb1a 59 _currentState = GATT_IDLE;
Andrea Palmieri 229:9981f62cdb1a 60 return;
Andrea Palmieri 229:9981f62cdb1a 61 }
Andrea Palmieri 229:9981f62cdb1a 62
Andrea Palmieri 229:9981f62cdb1a 63 // Service Discovery complete
Andrea Palmieri 229:9981f62cdb1a 64 /*
Andrea Palmieri 229:9981f62cdb1a 65 if(_currentState != GATT_IDLE &&
Andrea Palmieri 229:9981f62cdb1a 66 _currentState != GATT_DISCOVERY_TERMINATED &&
Andrea Palmieri 229:9981f62cdb1a 67 _currentState != GATT_WRITE_CHAR &&
Andrea Palmieri 229:9981f62cdb1a 68 _currentState != GATT_READ_CHAR) {
Andrea Palmieri 229:9981f62cdb1a 69 */
Andrea Palmieri 229:9981f62cdb1a 70 if(_currentState == GATT_SERVICE_DISCOVERY) {
Andrea Palmieri 229:9981f62cdb1a 71 findServiceChars(connectionHandle);
Andrea Palmieri 229:9981f62cdb1a 72 }
Andrea Palmieri 229:9981f62cdb1a 73
Andrea Palmieri 229:9981f62cdb1a 74 if(_currentState == GATT_CHAR_DESC_DISCOVERY) {
Andrea Palmieri 229:9981f62cdb1a 75 _currentState = GATT_IDLE;
Andrea Palmieri 229:9981f62cdb1a 76 }
Andrea Palmieri 229:9981f62cdb1a 77
Andrea Palmieri 229:9981f62cdb1a 78 // Read complete
Andrea Palmieri 229:9981f62cdb1a 79 if(_currentState == GATT_READ_CHAR) {
Andrea Palmieri 229:9981f62cdb1a 80 _currentState = GATT_IDLE;
Andrea Palmieri 229:9981f62cdb1a 81 }
Andrea Palmieri 229:9981f62cdb1a 82
Andrea Palmieri 229:9981f62cdb1a 83 // Write complete
Andrea Palmieri 229:9981f62cdb1a 84 if(_currentState == GATT_WRITE_CHAR) {
Andrea Palmieri 229:9981f62cdb1a 85 BlueNRGGattClient::getInstance().processWriteResponse(&writeCBParams);
Andrea Palmieri 229:9981f62cdb1a 86 _currentState = GATT_IDLE;
Andrea Palmieri 229:9981f62cdb1a 87 }
Andrea Palmieri 229:9981f62cdb1a 88 }
Andrea Palmieri 229:9981f62cdb1a 89
Andrea Palmieri 229:9981f62cdb1a 90 void BlueNRGGattClient::primaryServicesCB(Gap::Handle_t connectionHandle,
Andrea Palmieri 229:9981f62cdb1a 91 uint8_t event_data_length,
Andrea Palmieri 229:9981f62cdb1a 92 uint8_t attribute_data_length,
Andrea Palmieri 229:9981f62cdb1a 93 uint8_t *attribute_data_list)
Andrea Palmieri 229:9981f62cdb1a 94 {
Andrea Palmieri 229:9981f62cdb1a 95 GattAttribute::Handle_t startHandle, endHandle;
Andrea Palmieri 229:9981f62cdb1a 96 UUID uuid;
Andrea Palmieri 229:9981f62cdb1a 97 uint8_t i, offset, numAttr;
Andrea Palmieri 229:9981f62cdb1a 98 /* avoid compiler warnings about unused variables */
Andrea Palmieri 229:9981f62cdb1a 99 (void)connectionHandle;
Andrea Palmieri 229:9981f62cdb1a 100
Andrea Palmieri 229:9981f62cdb1a 101 numAttr = (event_data_length - 1) / attribute_data_length;
Andrea Palmieri 229:9981f62cdb1a 102
Andrea Palmieri 229:9981f62cdb1a 103 offset = 0;
Andrea Palmieri 229:9981f62cdb1a 104 for (i=0; i<numAttr; i++) {
Andrea Palmieri 229:9981f62cdb1a 105 startHandle = attribute_data_list[offset];
Andrea Palmieri 229:9981f62cdb1a 106 endHandle = attribute_data_list[offset+2];
Andrea Palmieri 229:9981f62cdb1a 107
Andrea Palmieri 229:9981f62cdb1a 108 // UUID Type
Andrea Palmieri 229:9981f62cdb1a 109 if (attribute_data_length == 6) {
Andrea Palmieri 229:9981f62cdb1a 110
Andrea Palmieri 229:9981f62cdb1a 111 PRINTF("UUID_TYPE_16\n\r");
Andrea Palmieri 229:9981f62cdb1a 112 uuid = attribute_data_list[offset+5]<<8|attribute_data_list[offset+4];
Andrea Palmieri 229:9981f62cdb1a 113 PRINTF("S UUID-%X attrs[%u %u]\r\n", uuid.getShortUUID(), startHandle, endHandle);
Andrea Palmieri 229:9981f62cdb1a 114
Andrea Palmieri 229:9981f62cdb1a 115 } else {
Andrea Palmieri 229:9981f62cdb1a 116
Andrea Palmieri 229:9981f62cdb1a 117 PRINTF("UUID_TYPE_128\n\r");
Andrea Palmieri 229:9981f62cdb1a 118 uuid.setupLong(attribute_data_list+offset+4, UUID::LSB);
Andrea Palmieri 229:9981f62cdb1a 119
Andrea Palmieri 229:9981f62cdb1a 120 #ifdef DEBUG
Andrea Palmieri 229:9981f62cdb1a 121 PRINTF("S UUID-");
Andrea Palmieri 229:9981f62cdb1a 122 const uint8_t *longUUIDBytes = uuid.getBaseUUID();
Andrea Palmieri 229:9981f62cdb1a 123 for (unsigned j = 0; j < UUID::LENGTH_OF_LONG_UUID; j++) {
Andrea Palmieri 229:9981f62cdb1a 124 PRINTF("%02x", longUUIDBytes[j]);
Andrea Palmieri 229:9981f62cdb1a 125 }
Andrea Palmieri 229:9981f62cdb1a 126 #endif
Andrea Palmieri 229:9981f62cdb1a 127 PRINTF(" attrs[%u %u]\r\n", startHandle, endHandle);
Andrea Palmieri 229:9981f62cdb1a 128
Andrea Palmieri 229:9981f62cdb1a 129 }
Andrea Palmieri 229:9981f62cdb1a 130
Andrea Palmieri 229:9981f62cdb1a 131 PRINTF("Setup serviceIndex = %d\n\r", _numServices);
Andrea Palmieri 229:9981f62cdb1a 132 discoveredService[_numServices].setup(uuid, startHandle, endHandle);
Andrea Palmieri 229:9981f62cdb1a 133
Andrea Palmieri 229:9981f62cdb1a 134 if(serviceDiscoveryCallback) {
Andrea Palmieri 229:9981f62cdb1a 135 if(_matchingServiceUUID == BLE_UUID_UNKNOWN || _matchingServiceUUID == discoveredService[_numServices].getUUID()) {
Andrea Palmieri 229:9981f62cdb1a 136 serviceDiscoveryCallback(&discoveredService[_numServices]);
Andrea Palmieri 229:9981f62cdb1a 137 }
Andrea Palmieri 229:9981f62cdb1a 138 }
Andrea Palmieri 229:9981f62cdb1a 139 _numServices++;
Andrea Palmieri 229:9981f62cdb1a 140
Andrea Palmieri 229:9981f62cdb1a 141 offset += attribute_data_length;
Andrea Palmieri 229:9981f62cdb1a 142 }
Andrea Palmieri 229:9981f62cdb1a 143
Andrea Palmieri 229:9981f62cdb1a 144 PRINTF("!!!Service Discovery complete (numAttr=%u)!!!\n\r", numAttr);
Andrea Palmieri 229:9981f62cdb1a 145
Andrea Palmieri 229:9981f62cdb1a 146 }
Andrea Palmieri 229:9981f62cdb1a 147
Andrea Palmieri 229:9981f62cdb1a 148 void BlueNRGGattClient::primaryServiceCB(Gap::Handle_t connectionHandle,
Andrea Palmieri 229:9981f62cdb1a 149 uint8_t event_data_length,
Andrea Palmieri 229:9981f62cdb1a 150 uint8_t *handles_info_list)
Andrea Palmieri 229:9981f62cdb1a 151 {
Andrea Palmieri 229:9981f62cdb1a 152 GattAttribute::Handle_t startHandle, endHandle;
Andrea Palmieri 229:9981f62cdb1a 153 UUID uuid;
Andrea Palmieri 229:9981f62cdb1a 154 uint8_t i, offset, numHandlePairs;
Andrea Palmieri 229:9981f62cdb1a 155 /* avoid compiler warnings about unused variables */
Andrea Palmieri 229:9981f62cdb1a 156 (void)connectionHandle;
Andrea Palmieri 229:9981f62cdb1a 157
Andrea Palmieri 229:9981f62cdb1a 158 numHandlePairs = (event_data_length - 1) / 2;
Andrea Palmieri 229:9981f62cdb1a 159
Andrea Palmieri 229:9981f62cdb1a 160 offset = 0;
Andrea Palmieri 229:9981f62cdb1a 161 for (i=0; i<numHandlePairs; i++) {
Andrea Palmieri 229:9981f62cdb1a 162 startHandle = handles_info_list[offset];
Andrea Palmieri 229:9981f62cdb1a 163 endHandle = handles_info_list[offset+2];
Andrea Palmieri 229:9981f62cdb1a 164
Andrea Palmieri 229:9981f62cdb1a 165 PRINTF("primaryServiceCB attrs[%u %u]\r\n", startHandle, endHandle);
Andrea Palmieri 229:9981f62cdb1a 166
Andrea Palmieri 229:9981f62cdb1a 167
Andrea Palmieri 229:9981f62cdb1a 168 if (_matchingServiceUUID.shortOrLong() == UUID::UUID_TYPE_SHORT) {
Andrea Palmieri 229:9981f62cdb1a 169 PRINTF("S UUID-%x attrs[%u %u]\r\n", _matchingServiceUUID.getShortUUID(), startHandle, endHandle);
Andrea Palmieri 229:9981f62cdb1a 170 uuid = _matchingServiceUUID.getShortUUID();
Andrea Palmieri 229:9981f62cdb1a 171 } else {
Andrea Palmieri 229:9981f62cdb1a 172 #ifdef DEBUG
Andrea Palmieri 229:9981f62cdb1a 173 PRINTF("S UUID-");
Andrea Palmieri 229:9981f62cdb1a 174 const uint8_t *longUUIDBytes = _matchingServiceUUID.getBaseUUID();
Andrea Palmieri 229:9981f62cdb1a 175 for (unsigned i = 0; i < UUID::LENGTH_OF_LONG_UUID; i++) {
Andrea Palmieri 229:9981f62cdb1a 176 PRINTF("%02x", longUUIDBytes[i]);
Andrea Palmieri 229:9981f62cdb1a 177 }
Andrea Palmieri 229:9981f62cdb1a 178 #endif
Andrea Palmieri 229:9981f62cdb1a 179 PRINTF(" attrs[%u %u]\r\n", startHandle, endHandle);
Andrea Palmieri 229:9981f62cdb1a 180 uuid.setupLong(_matchingServiceUUID.getBaseUUID(), UUID::MSB);
Andrea Palmieri 229:9981f62cdb1a 181 }
Andrea Palmieri 229:9981f62cdb1a 182
Andrea Palmieri 229:9981f62cdb1a 183 discoveredService[i].setup(uuid, startHandle, endHandle);
Andrea Palmieri 229:9981f62cdb1a 184
Andrea Palmieri 229:9981f62cdb1a 185 if(serviceDiscoveryCallback) {
Andrea Palmieri 229:9981f62cdb1a 186 serviceDiscoveryCallback(&discoveredService[_numServices]);
Andrea Palmieri 229:9981f62cdb1a 187 }
Andrea Palmieri 229:9981f62cdb1a 188 _numServices++;
Andrea Palmieri 229:9981f62cdb1a 189
Andrea Palmieri 229:9981f62cdb1a 190 offset += 4;
Andrea Palmieri 229:9981f62cdb1a 191 }
Andrea Palmieri 229:9981f62cdb1a 192 }
Andrea Palmieri 229:9981f62cdb1a 193
Andrea Palmieri 229:9981f62cdb1a 194 void BlueNRGGattClient::serviceCharsCB(Gap::Handle_t connectionHandle,
Andrea Palmieri 229:9981f62cdb1a 195 uint8_t event_data_length,
Andrea Palmieri 229:9981f62cdb1a 196 uint8_t handle_value_pair_length,
Andrea Palmieri 229:9981f62cdb1a 197 uint8_t *handle_value_pair)
Andrea Palmieri 229:9981f62cdb1a 198 {
Andrea Palmieri 229:9981f62cdb1a 199 // Charac Handle (2), Charac Properties(1), Charac Value Handle(2), Charac UUID(2/16)
Andrea Palmieri 229:9981f62cdb1a 200
Andrea Palmieri 229:9981f62cdb1a 201 GattAttribute::Handle_t declHandle, valueHandle, lastHandle;
Andrea Palmieri 229:9981f62cdb1a 202 UUID uuid;
Andrea Palmieri 229:9981f62cdb1a 203 uint8_t i, numChar, offset;
Andrea Palmieri 229:9981f62cdb1a 204
Andrea Palmieri 229:9981f62cdb1a 205 numChar = (event_data_length - 1) / handle_value_pair_length;
Andrea Palmieri 229:9981f62cdb1a 206
Andrea Palmieri 229:9981f62cdb1a 207 PRINTF("event_data_length=%d handle_value_pair_length=%d numChar=%d\n\r", event_data_length, handle_value_pair_length, numChar);
Andrea Palmieri 229:9981f62cdb1a 208
Andrea Palmieri 229:9981f62cdb1a 209 offset = 0;
Andrea Palmieri 229:9981f62cdb1a 210 for (i=0; i<numChar; i++) {
Andrea Palmieri 229:9981f62cdb1a 211 // UUID Type
Andrea Palmieri 229:9981f62cdb1a 212 if (handle_value_pair_length == 7) {
Andrea Palmieri 229:9981f62cdb1a 213 PRINTF("Char UUID_TYPE_16\n\r");
Andrea Palmieri 229:9981f62cdb1a 214 uuid = handle_value_pair[offset+6]<<8|handle_value_pair[offset+5];
Andrea Palmieri 229:9981f62cdb1a 215 PRINTF("C UUID-%X\r\n", uuid.getShortUUID());
Andrea Palmieri 229:9981f62cdb1a 216 } else {
Andrea Palmieri 229:9981f62cdb1a 217 PRINTF("Char UUID_TYPE_128\n\r");
Andrea Palmieri 229:9981f62cdb1a 218 uuid.setupLong(handle_value_pair+offset+5, UUID::LSB);
Andrea Palmieri 229:9981f62cdb1a 219 #ifdef DEBUG
Andrea Palmieri 229:9981f62cdb1a 220 PRINTF("C UUID-");
Andrea Palmieri 229:9981f62cdb1a 221 const uint8_t *longUUIDBytes = uuid.getBaseUUID();
Andrea Palmieri 229:9981f62cdb1a 222 for (unsigned i = 0; i < UUID::LENGTH_OF_LONG_UUID; i++) {
Andrea Palmieri 229:9981f62cdb1a 223 PRINTF("%02X", longUUIDBytes[i]);
Andrea Palmieri 229:9981f62cdb1a 224 }
Andrea Palmieri 229:9981f62cdb1a 225 PRINTF("\r\n");
Andrea Palmieri 229:9981f62cdb1a 226 #endif
Andrea Palmieri 229:9981f62cdb1a 227 }
Andrea Palmieri 229:9981f62cdb1a 228
Andrea Palmieri 229:9981f62cdb1a 229 // Properties
Andrea Palmieri 229:9981f62cdb1a 230 DiscoveredCharacteristic::Properties_t p;
Andrea Palmieri 229:9981f62cdb1a 231
Andrea Palmieri 229:9981f62cdb1a 232 p._broadcast = (props_mask[0] & handle_value_pair[offset+2]);
Andrea Palmieri 229:9981f62cdb1a 233 p._read = (props_mask[1] & handle_value_pair[offset+2])>>1;
Andrea Palmieri 229:9981f62cdb1a 234 p._writeWoResp = (props_mask[2] & handle_value_pair[offset+2])>>2;
Andrea Palmieri 229:9981f62cdb1a 235 p._write = (props_mask[3] & handle_value_pair[offset+2])>>3;
Andrea Palmieri 229:9981f62cdb1a 236 p._notify = (props_mask[4] & handle_value_pair[offset+2])>>4;
Andrea Palmieri 229:9981f62cdb1a 237 p._indicate = (props_mask[5] & handle_value_pair[offset+2])>>5;
Andrea Palmieri 229:9981f62cdb1a 238 p._authSignedWrite = (props_mask[6] & handle_value_pair[offset+2])>>6;
Andrea Palmieri 229:9981f62cdb1a 239 PRINTF("p._broadcast=%d\n\r", p._broadcast);
Andrea Palmieri 229:9981f62cdb1a 240 PRINTF("p._read=%d\n\r", p._read);
Andrea Palmieri 229:9981f62cdb1a 241 PRINTF("p._writeWoResp=%d\n\r", p._writeWoResp);
Andrea Palmieri 229:9981f62cdb1a 242 PRINTF("p._write=%d\n\r", p._write);
Andrea Palmieri 229:9981f62cdb1a 243 PRINTF("p._notify=%d\n\r", p._notify);
Andrea Palmieri 229:9981f62cdb1a 244 PRINTF("p._indicate=%d\n\r", p._indicate);
Andrea Palmieri 229:9981f62cdb1a 245 PRINTF("p._authSignedWrite=%d\n\r", p._authSignedWrite);
Andrea Palmieri 229:9981f62cdb1a 246
Andrea Palmieri 229:9981f62cdb1a 247 /*
Andrea Palmieri 229:9981f62cdb1a 248 uint8_t props = handle_value_pair[offset+2];
Andrea Palmieri 229:9981f62cdb1a 249 PRINTF("CHAR PROPS: %d\n\r", props);
Andrea Palmieri 229:9981f62cdb1a 250 */
Andrea Palmieri 229:9981f62cdb1a 251
Andrea Palmieri 229:9981f62cdb1a 252 // Handles
Andrea Palmieri 229:9981f62cdb1a 253 declHandle = handle_value_pair[offset];
Andrea Palmieri 229:9981f62cdb1a 254 valueHandle = handle_value_pair[offset+3];
Andrea Palmieri 229:9981f62cdb1a 255 lastHandle = valueHandle+1;
Andrea Palmieri 229:9981f62cdb1a 256 PRINTF("declHandle: %u valueHandle=%u lastHandle=%u\n\r", declHandle, valueHandle, lastHandle);
Andrea Palmieri 229:9981f62cdb1a 257
Andrea Palmieri 229:9981f62cdb1a 258 discoveredChar[_numChars].setup(this,
Andrea Palmieri 229:9981f62cdb1a 259 connectionHandle,
Andrea Palmieri 229:9981f62cdb1a 260 uuid,
Andrea Palmieri 229:9981f62cdb1a 261 p,
Andrea Palmieri 229:9981f62cdb1a 262 declHandle,
Andrea Palmieri 229:9981f62cdb1a 263 valueHandle,
Andrea Palmieri 229:9981f62cdb1a 264 lastHandle);
Andrea Palmieri 229:9981f62cdb1a 265
Andrea Palmieri 229:9981f62cdb1a 266 if(characteristicDiscoveryCallback) {
Andrea Palmieri 229:9981f62cdb1a 267 characteristicDiscoveryCallback(&discoveredChar[_numChars]);
Andrea Palmieri 229:9981f62cdb1a 268 }
Andrea Palmieri 229:9981f62cdb1a 269 _numChars++;
Andrea Palmieri 229:9981f62cdb1a 270
Andrea Palmieri 229:9981f62cdb1a 271 offset += handle_value_pair_length;
Andrea Palmieri 229:9981f62cdb1a 272 }
Andrea Palmieri 229:9981f62cdb1a 273 }
Andrea Palmieri 229:9981f62cdb1a 274
Andrea Palmieri 229:9981f62cdb1a 275 void BlueNRGGattClient::serviceCharByUUIDCB(Gap::Handle_t connectionHandle,
Andrea Palmieri 229:9981f62cdb1a 276 uint8_t event_data_length,
Andrea Palmieri 229:9981f62cdb1a 277 uint16_t attr_handle,
Andrea Palmieri 229:9981f62cdb1a 278 uint8_t *attr_value)
Andrea Palmieri 229:9981f62cdb1a 279 {
Andrea Palmieri 229:9981f62cdb1a 280 // Charac Properties(1), Charac Value Handle(2), Charac UUID(2/16)
Andrea Palmieri 229:9981f62cdb1a 281 GattAttribute::Handle_t declHandle, valueHandle, lastHandle;
Andrea Palmieri 229:9981f62cdb1a 282 UUID uuid;
Andrea Palmieri 229:9981f62cdb1a 283
Andrea Palmieri 229:9981f62cdb1a 284 PRINTF("serviceCharByUUIDCB\n\r");
Andrea Palmieri 229:9981f62cdb1a 285
Andrea Palmieri 229:9981f62cdb1a 286 // UUID Type
Andrea Palmieri 229:9981f62cdb1a 287 if (event_data_length == 7) {
Andrea Palmieri 229:9981f62cdb1a 288 PRINTF("Char UUID_TYPE_16\n\r");
Andrea Palmieri 229:9981f62cdb1a 289 uuid = attr_value[4]<<8|attr_value[3];
Andrea Palmieri 229:9981f62cdb1a 290 PRINTF("C UUID-%X\r\n", uuid.getShortUUID());
Andrea Palmieri 229:9981f62cdb1a 291 } else {
Andrea Palmieri 229:9981f62cdb1a 292 PRINTF("Char UUID_TYPE_128\n\r");
Andrea Palmieri 229:9981f62cdb1a 293 uuid.setupLong(attr_value+3, UUID::LSB);
Andrea Palmieri 229:9981f62cdb1a 294 #ifdef DEBUG
Andrea Palmieri 229:9981f62cdb1a 295 PRINTF("C UUID-");
Andrea Palmieri 229:9981f62cdb1a 296 const uint8_t *longUUIDBytes = uuid.getBaseUUID();
Andrea Palmieri 229:9981f62cdb1a 297 for (unsigned i = 0; i < UUID::LENGTH_OF_LONG_UUID; i++) {
Andrea Palmieri 229:9981f62cdb1a 298 PRINTF("%02X", longUUIDBytes[i]);
Andrea Palmieri 229:9981f62cdb1a 299 }
Andrea Palmieri 229:9981f62cdb1a 300 PRINTF("\r\n");
Andrea Palmieri 229:9981f62cdb1a 301 #endif
Andrea Palmieri 229:9981f62cdb1a 302 }
Andrea Palmieri 229:9981f62cdb1a 303
Andrea Palmieri 229:9981f62cdb1a 304 // Properties
Andrea Palmieri 229:9981f62cdb1a 305 DiscoveredCharacteristic::Properties_t p;
Andrea Palmieri 229:9981f62cdb1a 306
Andrea Palmieri 229:9981f62cdb1a 307 p._broadcast = (props_mask[0] & attr_value[0]);
Andrea Palmieri 229:9981f62cdb1a 308 p._read = (props_mask[1] & attr_value[0])>>1;
Andrea Palmieri 229:9981f62cdb1a 309 p._writeWoResp = (props_mask[2] & attr_value[0])>>2;
Andrea Palmieri 229:9981f62cdb1a 310 p._write = (props_mask[3] & attr_value[0])>>3;
Andrea Palmieri 229:9981f62cdb1a 311 p._notify = (props_mask[4] & attr_value[0])>>4;
Andrea Palmieri 229:9981f62cdb1a 312 p._indicate = (props_mask[5] & attr_value[0])>>5;
Andrea Palmieri 229:9981f62cdb1a 313 p._authSignedWrite = (props_mask[6] & attr_value[0])>>6;
Andrea Palmieri 229:9981f62cdb1a 314 PRINTF("p._broadcast=%d\n\r", p._broadcast);
Andrea Palmieri 229:9981f62cdb1a 315 PRINTF("p._read=%d\n\r", p._read);
Andrea Palmieri 229:9981f62cdb1a 316 PRINTF("p._writeWoResp=%d\n\r", p._writeWoResp);
Andrea Palmieri 229:9981f62cdb1a 317 PRINTF("p._write=%d\n\r", p._write);
Andrea Palmieri 229:9981f62cdb1a 318 PRINTF("p._notify=%d\n\r", p._notify);
Andrea Palmieri 229:9981f62cdb1a 319 PRINTF("p._indicate=%d\n\r", p._indicate);
Andrea Palmieri 229:9981f62cdb1a 320 PRINTF("p._authSignedWrite=%d\n\r", p._authSignedWrite);
Andrea Palmieri 229:9981f62cdb1a 321
Andrea Palmieri 229:9981f62cdb1a 322 /*
Andrea Palmieri 229:9981f62cdb1a 323 uint8_t props = attr_value[0];
Andrea Palmieri 229:9981f62cdb1a 324 PRINTF("CHAR PROPS: %d\n\r", props);
Andrea Palmieri 229:9981f62cdb1a 325 */
Andrea Palmieri 229:9981f62cdb1a 326
Andrea Palmieri 229:9981f62cdb1a 327 // Handles
Andrea Palmieri 229:9981f62cdb1a 328 declHandle = attr_handle;
Andrea Palmieri 229:9981f62cdb1a 329 valueHandle = attr_value[1];
Andrea Palmieri 229:9981f62cdb1a 330 lastHandle = valueHandle+1;
Andrea Palmieri 229:9981f62cdb1a 331
Andrea Palmieri 229:9981f62cdb1a 332 discoveredChar[_numChars].setup(this,
Andrea Palmieri 229:9981f62cdb1a 333 connectionHandle,
Andrea Palmieri 229:9981f62cdb1a 334 uuid,
Andrea Palmieri 229:9981f62cdb1a 335 p,
Andrea Palmieri 229:9981f62cdb1a 336 declHandle,
Andrea Palmieri 229:9981f62cdb1a 337 valueHandle,
Andrea Palmieri 229:9981f62cdb1a 338 lastHandle);
Andrea Palmieri 229:9981f62cdb1a 339
Andrea Palmieri 229:9981f62cdb1a 340 if(characteristicDiscoveryCallback) {
Andrea Palmieri 229:9981f62cdb1a 341 characteristicDiscoveryCallback(&discoveredChar[_numChars]);
Andrea Palmieri 229:9981f62cdb1a 342 }
Andrea Palmieri 229:9981f62cdb1a 343 _numChars++;
Andrea Palmieri 229:9981f62cdb1a 344 }
Andrea Palmieri 229:9981f62cdb1a 345
Andrea Palmieri 229:9981f62cdb1a 346 ble_error_t BlueNRGGattClient::findServiceChars(Gap::Handle_t connectionHandle)
Andrea Palmieri 229:9981f62cdb1a 347 {
Andrea Palmieri 229:9981f62cdb1a 348 PRINTF("findServiceChars\n\r");
Andrea Palmieri 229:9981f62cdb1a 349
Andrea Palmieri 229:9981f62cdb1a 350 tBleStatus ret;
Andrea Palmieri 229:9981f62cdb1a 351 uint8_t uuid_type = UUID_TYPE_16;
Andrea Palmieri 229:9981f62cdb1a 352 uint8_t short_uuid[2];
Andrea Palmieri 229:9981f62cdb1a 353 uint8_t *uuid = NULL;
Andrea Palmieri 229:9981f62cdb1a 354
Andrea Palmieri 229:9981f62cdb1a 355 DiscoveredService *service;
Andrea Palmieri 229:9981f62cdb1a 356
Andrea Palmieri 229:9981f62cdb1a 357 // We finished chars discovery for all services
Andrea Palmieri 229:9981f62cdb1a 358 if(_servIndex >= _numServices) {
Andrea Palmieri 229:9981f62cdb1a 359 PRINTF("!!!We finished chars discovery for all services!!!\n\r");
Andrea Palmieri 229:9981f62cdb1a 360 //_currentState = GATT_CHARS_DISCOVERY_COMPLETE;
Andrea Palmieri 229:9981f62cdb1a 361
Andrea Palmieri 229:9981f62cdb1a 362 terminateServiceDiscovery();
Andrea Palmieri 229:9981f62cdb1a 363
Andrea Palmieri 229:9981f62cdb1a 364 return BLE_ERROR_NONE;
Andrea Palmieri 229:9981f62cdb1a 365 }
Andrea Palmieri 229:9981f62cdb1a 366
Andrea Palmieri 229:9981f62cdb1a 367 service = &discoveredService[_servIndex];
Andrea Palmieri 229:9981f62cdb1a 368 /*
Andrea Palmieri 229:9981f62cdb1a 369 if (service->getUUID().shortOrLong() == UUID::UUID_TYPE_SHORT) {
Andrea Palmieri 229:9981f62cdb1a 370 PRINTF("S UUID-%X\r\n", service->getUUID().getShortUUID());
Andrea Palmieri 229:9981f62cdb1a 371 } else {
Andrea Palmieri 229:9981f62cdb1a 372 PRINTF("S UUID-");
Andrea Palmieri 229:9981f62cdb1a 373 const uint8_t *longUUIDBytes = service->getUUID().getBaseUUID();
Andrea Palmieri 229:9981f62cdb1a 374 for (unsigned i = 0; i < UUID::LENGTH_OF_LONG_UUID; i++) {
Andrea Palmieri 229:9981f62cdb1a 375 PRINTF("%02X", longUUIDBytes[i]);
Andrea Palmieri 229:9981f62cdb1a 376 }
Andrea Palmieri 229:9981f62cdb1a 377 PRINTF("\r\n");
Andrea Palmieri 229:9981f62cdb1a 378 }
Andrea Palmieri 229:9981f62cdb1a 379 */
Andrea Palmieri 229:9981f62cdb1a 380
Andrea Palmieri 229:9981f62cdb1a 381 PRINTF("findServiceChars (_servIndex=%d)\n\r", _servIndex);
Andrea Palmieri 229:9981f62cdb1a 382 //ret = aci_gatt_disc_all_charac_of_serv(connectionHandle, service->getStartHandle(), service->getEndHandle());
Andrea Palmieri 229:9981f62cdb1a 383
Andrea Palmieri 229:9981f62cdb1a 384 if(_matchingCharacteristicUUIDIn == BLE_UUID_UNKNOWN) {
Andrea Palmieri 229:9981f62cdb1a 385 PRINTF("findServiceChars (BLE_UUID_UNKNOWN)\n\r");
Andrea Palmieri 229:9981f62cdb1a 386 ret = aci_gatt_disc_all_charac_of_serv(connectionHandle, service->getStartHandle(), service->getEndHandle());
Andrea Palmieri 229:9981f62cdb1a 387 } else {
Andrea Palmieri 229:9981f62cdb1a 388
Andrea Palmieri 229:9981f62cdb1a 389 uint8_t type = _matchingCharacteristicUUIDIn.shortOrLong();
Andrea Palmieri 229:9981f62cdb1a 390
Andrea Palmieri 229:9981f62cdb1a 391 if(type == UUID::UUID_TYPE_SHORT) {
Andrea Palmieri 229:9981f62cdb1a 392 STORE_LE_16(short_uuid, _matchingCharacteristicUUIDIn.getShortUUID());
Andrea Palmieri 229:9981f62cdb1a 393
Andrea Palmieri 229:9981f62cdb1a 394 uuid_type = UUID_TYPE_16;
Andrea Palmieri 229:9981f62cdb1a 395 uuid = short_uuid;
Andrea Palmieri 229:9981f62cdb1a 396 #ifdef DEBUG
Andrea Palmieri 229:9981f62cdb1a 397 PRINTF("findServiceChars C UUID-");
Andrea Palmieri 229:9981f62cdb1a 398 for(unsigned i = 0; i < 2; i++) {
Andrea Palmieri 229:9981f62cdb1a 399 PRINTF("%02X", short_uuid[i]);
Andrea Palmieri 229:9981f62cdb1a 400 }
Andrea Palmieri 229:9981f62cdb1a 401 PRINTF("\n\r");
Andrea Palmieri 229:9981f62cdb1a 402 #endif
Andrea Palmieri 229:9981f62cdb1a 403 } else if(type==UUID::UUID_TYPE_LONG) {
Andrea Palmieri 229:9981f62cdb1a 404
Andrea Palmieri 229:9981f62cdb1a 405 uuid_type = UUID_TYPE_128;
Andrea Palmieri 229:9981f62cdb1a 406 uuid = (unsigned char*)_matchingCharacteristicUUIDIn.getBaseUUID();
Andrea Palmieri 229:9981f62cdb1a 407 #ifdef DEBUG
Andrea Palmieri 229:9981f62cdb1a 408 PRINTF("(findServiceChars) C UUID-");
Andrea Palmieri 229:9981f62cdb1a 409 for (unsigned i = 0; i < UUID::LENGTH_OF_LONG_UUID; i++) {
Andrea Palmieri 229:9981f62cdb1a 410 PRINTF("%02X", uuid[i]);
Andrea Palmieri 229:9981f62cdb1a 411 }
Andrea Palmieri 229:9981f62cdb1a 412 PRINTF("\r\n");
Andrea Palmieri 229:9981f62cdb1a 413 #endif
Andrea Palmieri 229:9981f62cdb1a 414 }
Andrea Palmieri 229:9981f62cdb1a 415
Andrea Palmieri 229:9981f62cdb1a 416 ret = aci_gatt_disc_charac_by_uuid(connectionHandle,
Andrea Palmieri 229:9981f62cdb1a 417 service->getStartHandle(),
Andrea Palmieri 229:9981f62cdb1a 418 service->getEndHandle(),
Andrea Palmieri 229:9981f62cdb1a 419 uuid_type,
Andrea Palmieri 229:9981f62cdb1a 420 uuid);
Andrea Palmieri 229:9981f62cdb1a 421 }
Andrea Palmieri 229:9981f62cdb1a 422
Andrea Palmieri 229:9981f62cdb1a 423 if(ret == BLE_STATUS_SUCCESS) {
Andrea Palmieri 229:9981f62cdb1a 424 _servIndex++;
Andrea Palmieri 229:9981f62cdb1a 425 }
Andrea Palmieri 229:9981f62cdb1a 426
Andrea Palmieri 229:9981f62cdb1a 427 PRINTF("findServiceChars ret=%d\n\r", ret);
Andrea Palmieri 229:9981f62cdb1a 428
Andrea Palmieri 229:9981f62cdb1a 429 return BLE_ERROR_NONE;
Andrea Palmieri 229:9981f62cdb1a 430 }
Andrea Palmieri 229:9981f62cdb1a 431
Andrea Palmieri 229:9981f62cdb1a 432 ble_error_t BlueNRGGattClient::launchServiceDiscovery(Gap::Handle_t connectionHandle,
Andrea Palmieri 229:9981f62cdb1a 433 ServiceDiscovery::ServiceCallback_t sc,
Andrea Palmieri 229:9981f62cdb1a 434 ServiceDiscovery::CharacteristicCallback_t cc,
Andrea Palmieri 229:9981f62cdb1a 435 const UUID &matchingServiceUUID,
Andrea Palmieri 229:9981f62cdb1a 436 const UUID &matchingCharacteristicUUIDIn)
Andrea Palmieri 229:9981f62cdb1a 437 {
Andrea Palmieri 229:9981f62cdb1a 438 PRINTF("launchServiceDiscovery\n\r");
Andrea Palmieri 229:9981f62cdb1a 439
Andrea Palmieri 229:9981f62cdb1a 440 tBleStatus ret;
Andrea Palmieri 229:9981f62cdb1a 441 uint8_t uuid_type = UUID_TYPE_16;
Andrea Palmieri 229:9981f62cdb1a 442 uint8_t short_uuid[2];
Andrea Palmieri 229:9981f62cdb1a 443 uint8_t *uuid = NULL;
Andrea Palmieri 229:9981f62cdb1a 444 unsigned j;
Andrea Palmieri 229:9981f62cdb1a 445
Andrea Palmieri 229:9981f62cdb1a 446 if(isServiceDiscoveryActive()) {
Andrea Palmieri 229:9981f62cdb1a 447 return BLE_ERROR_OPERATION_NOT_PERMITTED;
Andrea Palmieri 229:9981f62cdb1a 448 }
Andrea Palmieri 229:9981f62cdb1a 449
Andrea Palmieri 229:9981f62cdb1a 450 if(!sc && !cc) {
Andrea Palmieri 229:9981f62cdb1a 451 // nothing to do
Andrea Palmieri 229:9981f62cdb1a 452 PRINTF("launchServiceDiscovery: nothing to do\n\r");
Andrea Palmieri 229:9981f62cdb1a 453 return BLE_ERROR_NONE;
Andrea Palmieri 229:9981f62cdb1a 454 }
Andrea Palmieri 229:9981f62cdb1a 455
Andrea Palmieri 229:9981f62cdb1a 456 _connectionHandle = connectionHandle;
Andrea Palmieri 229:9981f62cdb1a 457 serviceDiscoveryCallback = sc;
Andrea Palmieri 229:9981f62cdb1a 458 characteristicDiscoveryCallback = cc;
Andrea Palmieri 229:9981f62cdb1a 459 _matchingServiceUUID = matchingServiceUUID;
Andrea Palmieri 229:9981f62cdb1a 460 _matchingCharacteristicUUIDIn = matchingCharacteristicUUIDIn;
Andrea Palmieri 229:9981f62cdb1a 461
Andrea Palmieri 229:9981f62cdb1a 462 //reset services
Andrea Palmieri 229:9981f62cdb1a 463 _numServices = 0;
Andrea Palmieri 229:9981f62cdb1a 464 _numChars = 0;
Andrea Palmieri 229:9981f62cdb1a 465 _servIndex = 0;
Andrea Palmieri 229:9981f62cdb1a 466 for(j = 0; j < BLE_TOTAL_DISCOVERED_SERVICES; j++) {
Andrea Palmieri 229:9981f62cdb1a 467 discoveredService[j].setup(BLE_UUID_UNKNOWN, GattAttribute::INVALID_HANDLE, GattAttribute::INVALID_HANDLE);
Andrea Palmieri 229:9981f62cdb1a 468 }
Andrea Palmieri 229:9981f62cdb1a 469
Andrea Palmieri 229:9981f62cdb1a 470 if(matchingServiceUUID == BLE_UUID_UNKNOWN) {
Andrea Palmieri 229:9981f62cdb1a 471
Andrea Palmieri 229:9981f62cdb1a 472 // Wildcard: search for all services
Andrea Palmieri 229:9981f62cdb1a 473 ret = aci_gatt_disc_all_prim_services((uint16_t)connectionHandle);
Andrea Palmieri 229:9981f62cdb1a 474
Andrea Palmieri 229:9981f62cdb1a 475 } else {
Andrea Palmieri 229:9981f62cdb1a 476
Andrea Palmieri 229:9981f62cdb1a 477 uint8_t type = matchingServiceUUID.shortOrLong();
Andrea Palmieri 229:9981f62cdb1a 478 //PRINTF("AddService(): Type:%d\n\r", type);
Andrea Palmieri 229:9981f62cdb1a 479
Andrea Palmieri 229:9981f62cdb1a 480 if(type == UUID::UUID_TYPE_SHORT) {
Andrea Palmieri 229:9981f62cdb1a 481 STORE_LE_16(short_uuid, matchingServiceUUID.getShortUUID());
Andrea Palmieri 229:9981f62cdb1a 482 #ifdef DEBUG
Andrea Palmieri 229:9981f62cdb1a 483 PRINTF("launchServiceDiscovery short_uuid=0x");
Andrea Palmieri 229:9981f62cdb1a 484 for(j = 0; j < 2; j++) {
Andrea Palmieri 229:9981f62cdb1a 485 PRINTF("%02X", short_uuid[j]);
Andrea Palmieri 229:9981f62cdb1a 486 }
Andrea Palmieri 229:9981f62cdb1a 487 PRINTF("\n\r");
Andrea Palmieri 229:9981f62cdb1a 488 #endif
Andrea Palmieri 229:9981f62cdb1a 489
Andrea Palmieri 229:9981f62cdb1a 490 uuid_type = UUID_TYPE_16;
Andrea Palmieri 229:9981f62cdb1a 491 uuid = short_uuid;
Andrea Palmieri 229:9981f62cdb1a 492
Andrea Palmieri 229:9981f62cdb1a 493 } else if(type==UUID::UUID_TYPE_LONG) {
Andrea Palmieri 229:9981f62cdb1a 494
Andrea Palmieri 229:9981f62cdb1a 495 uuid_type = UUID_TYPE_128;
Andrea Palmieri 229:9981f62cdb1a 496 uuid = (unsigned char*)matchingServiceUUID.getBaseUUID();
Andrea Palmieri 229:9981f62cdb1a 497
Andrea Palmieri 229:9981f62cdb1a 498 #ifdef DEBUG
Andrea Palmieri 229:9981f62cdb1a 499 PRINTF("launchServiceDiscovery base_uuid=0x");
Andrea Palmieri 229:9981f62cdb1a 500 for(j = 0; j < 16; j++) {
Andrea Palmieri 229:9981f62cdb1a 501 PRINTF("%02X", uuid[j]);
Andrea Palmieri 229:9981f62cdb1a 502 }
Andrea Palmieri 229:9981f62cdb1a 503 PRINTF("\n\r");
Andrea Palmieri 229:9981f62cdb1a 504 #endif
Andrea Palmieri 229:9981f62cdb1a 505 }
Andrea Palmieri 229:9981f62cdb1a 506
Andrea Palmieri 229:9981f62cdb1a 507 // search for specific service by UUID
Andrea Palmieri 229:9981f62cdb1a 508 ret = aci_gatt_disc_prim_service_by_uuid((uint16_t)connectionHandle, uuid_type, uuid);
Andrea Palmieri 229:9981f62cdb1a 509 //ret = aci_gatt_disc_all_prim_services((uint16_t)connectionHandle);
Andrea Palmieri 229:9981f62cdb1a 510 }
Andrea Palmieri 229:9981f62cdb1a 511
Andrea Palmieri 229:9981f62cdb1a 512 if(ret == BLE_STATUS_SUCCESS) {
Andrea Palmieri 229:9981f62cdb1a 513 _currentState = GATT_SERVICE_DISCOVERY;
Andrea Palmieri 229:9981f62cdb1a 514 }
Andrea Palmieri 229:9981f62cdb1a 515
Andrea Palmieri 229:9981f62cdb1a 516 PRINTF("launchServiceDiscovery ret=%d\n\r", ret);
Andrea Palmieri 229:9981f62cdb1a 517
Andrea Palmieri 229:9981f62cdb1a 518 return BLE_ERROR_NONE;
Andrea Palmieri 229:9981f62cdb1a 519 }
Andrea Palmieri 229:9981f62cdb1a 520
Andrea Palmieri 229:9981f62cdb1a 521 ble_error_t BlueNRGGattClient::discoverServices(Gap::Handle_t connectionHandle,
Andrea Palmieri 229:9981f62cdb1a 522 ServiceDiscovery::ServiceCallback_t callback,
Andrea Palmieri 229:9981f62cdb1a 523 const UUID &matchingServiceUUID)
Andrea Palmieri 229:9981f62cdb1a 524 {
Andrea Palmieri 229:9981f62cdb1a 525 /* avoid compiler warnings about unused variables */
Andrea Palmieri 229:9981f62cdb1a 526 (void)connectionHandle;
Andrea Palmieri 229:9981f62cdb1a 527 (void)callback;
Andrea Palmieri 229:9981f62cdb1a 528 (void)matchingServiceUUID;
Andrea Palmieri 229:9981f62cdb1a 529
Andrea Palmieri 229:9981f62cdb1a 530 return BLE_ERROR_NOT_IMPLEMENTED;
Andrea Palmieri 229:9981f62cdb1a 531 }
Andrea Palmieri 229:9981f62cdb1a 532
Andrea Palmieri 229:9981f62cdb1a 533 ble_error_t BlueNRGGattClient::discoverServices(Gap::Handle_t connectionHandle,
Andrea Palmieri 229:9981f62cdb1a 534 ServiceDiscovery::ServiceCallback_t callback,
Andrea Palmieri 229:9981f62cdb1a 535 GattAttribute::Handle_t startHandle,
Andrea Palmieri 229:9981f62cdb1a 536 GattAttribute::Handle_t endHandle)
Andrea Palmieri 229:9981f62cdb1a 537 {
Andrea Palmieri 229:9981f62cdb1a 538 /* avoid compiler warnings about unused variables */
Andrea Palmieri 229:9981f62cdb1a 539 (void)connectionHandle;
Andrea Palmieri 229:9981f62cdb1a 540 (void)callback;
Andrea Palmieri 229:9981f62cdb1a 541 (void)startHandle;
Andrea Palmieri 229:9981f62cdb1a 542 (void)endHandle;
Andrea Palmieri 229:9981f62cdb1a 543
Andrea Palmieri 229:9981f62cdb1a 544 return BLE_ERROR_NOT_IMPLEMENTED;
Andrea Palmieri 229:9981f62cdb1a 545 }
Andrea Palmieri 229:9981f62cdb1a 546
Andrea Palmieri 229:9981f62cdb1a 547 bool BlueNRGGattClient::isServiceDiscoveryActive(void) const
Andrea Palmieri 229:9981f62cdb1a 548 {
Andrea Palmieri 229:9981f62cdb1a 549 if(_currentState == GATT_SERVICE_DISCOVERY) {
Andrea Palmieri 229:9981f62cdb1a 550 return true;
Andrea Palmieri 229:9981f62cdb1a 551 }
Andrea Palmieri 229:9981f62cdb1a 552
Andrea Palmieri 229:9981f62cdb1a 553 return false;
Andrea Palmieri 229:9981f62cdb1a 554 /*
Andrea Palmieri 229:9981f62cdb1a 555 if(_currentState == GATT_IDLE ||
Andrea Palmieri 229:9981f62cdb1a 556 _currentState == GATT_DISCOVERY_TERMINATED ||
Andrea Palmieri 229:9981f62cdb1a 557 _currentState == GATT_READ_CHAR ||
Andrea Palmieri 229:9981f62cdb1a 558 _currentState == GATT_WRITE_CHAR ) {
Andrea Palmieri 229:9981f62cdb1a 559 return false;
Andrea Palmieri 229:9981f62cdb1a 560 }
Andrea Palmieri 229:9981f62cdb1a 561
Andrea Palmieri 229:9981f62cdb1a 562 return true;
Andrea Palmieri 229:9981f62cdb1a 563 */
Andrea Palmieri 229:9981f62cdb1a 564 }
Andrea Palmieri 229:9981f62cdb1a 565
Andrea Palmieri 229:9981f62cdb1a 566 void BlueNRGGattClient::terminateServiceDiscovery(void)
Andrea Palmieri 229:9981f62cdb1a 567 {
Andrea Palmieri 229:9981f62cdb1a 568 _currentState = GATT_IDLE;//GATT_DISCOVERY_TERMINATED;
Andrea Palmieri 229:9981f62cdb1a 569
Andrea Palmieri 229:9981f62cdb1a 570 if (terminationCallback) {
Andrea Palmieri 229:9981f62cdb1a 571 terminationCallback(_connectionHandle);
Andrea Palmieri 229:9981f62cdb1a 572 }
Andrea Palmieri 229:9981f62cdb1a 573 }
Andrea Palmieri 229:9981f62cdb1a 574
Andrea Palmieri 229:9981f62cdb1a 575 void BlueNRGGattClient::charReadCB(Gap::Handle_t connHandle,
Andrea Palmieri 229:9981f62cdb1a 576 uint8_t event_data_length,
Andrea Palmieri 229:9981f62cdb1a 577 uint8_t* attribute_value)
Andrea Palmieri 229:9981f62cdb1a 578 {
Andrea Palmieri 229:9981f62cdb1a 579 readCBParams.connHandle = connHandle;
Andrea Palmieri 229:9981f62cdb1a 580 readCBParams.offset = 0;
Andrea Palmieri 229:9981f62cdb1a 581 readCBParams.len = event_data_length;
Andrea Palmieri 229:9981f62cdb1a 582 readCBParams.data = attribute_value;
Andrea Palmieri 229:9981f62cdb1a 583
Andrea Palmieri 229:9981f62cdb1a 584 BlueNRGGattClient::getInstance().processReadResponse(&readCBParams);
Andrea Palmieri 229:9981f62cdb1a 585 }
Andrea Palmieri 229:9981f62cdb1a 586
Andrea Palmieri 229:9981f62cdb1a 587 ble_error_t BlueNRGGattClient::read(Gap::Handle_t connHandle, GattAttribute::Handle_t attributeHandle, uint16_t offset) const
Andrea Palmieri 229:9981f62cdb1a 588 {
Andrea Palmieri 229:9981f62cdb1a 589 /* avoid compiler warnings about unused variables */
Andrea Palmieri 229:9981f62cdb1a 590 (void)offset;
Andrea Palmieri 229:9981f62cdb1a 591
Andrea Palmieri 229:9981f62cdb1a 592 tBleStatus ret;
Andrea Palmieri 229:9981f62cdb1a 593
Andrea Palmieri 229:9981f62cdb1a 594 BlueNRGGattClient *gattc = const_cast<BlueNRGGattClient*>(this);
Andrea Palmieri 229:9981f62cdb1a 595
Andrea Palmieri 229:9981f62cdb1a 596 // Save the attribute_handle not provided by evt_att_read_resp
Andrea Palmieri 229:9981f62cdb1a 597 gattc->readCBParams.handle = attributeHandle;
Andrea Palmieri 229:9981f62cdb1a 598
Andrea Palmieri 229:9981f62cdb1a 599 // FIXME: We need to wait for a while before starting a read
Andrea Palmieri 229:9981f62cdb1a 600 // due to BlueNRG process queue handling
Andrea Palmieri 229:9981f62cdb1a 601 Clock_Wait(100);
Andrea Palmieri 229:9981f62cdb1a 602
Andrea Palmieri 229:9981f62cdb1a 603 ret = aci_gatt_read_charac_val(connHandle, attributeHandle);
Andrea Palmieri 229:9981f62cdb1a 604
Andrea Palmieri 229:9981f62cdb1a 605 if(ret == BLE_STATUS_SUCCESS) {
Andrea Palmieri 229:9981f62cdb1a 606 gattc->_currentState = GATT_READ_CHAR;
Andrea Palmieri 229:9981f62cdb1a 607 return BLE_ERROR_NONE;
Andrea Palmieri 229:9981f62cdb1a 608 }
Andrea Palmieri 229:9981f62cdb1a 609 switch (ret) {
Andrea Palmieri 229:9981f62cdb1a 610 case BLE_STATUS_BUSY:
Andrea Palmieri 229:9981f62cdb1a 611 return BLE_STACK_BUSY;
Andrea Palmieri 229:9981f62cdb1a 612 default:
Andrea Palmieri 229:9981f62cdb1a 613 return BLE_ERROR_INVALID_STATE;
Andrea Palmieri 229:9981f62cdb1a 614 }
Andrea Palmieri 229:9981f62cdb1a 615 }
Andrea Palmieri 229:9981f62cdb1a 616
Andrea Palmieri 229:9981f62cdb1a 617 void BlueNRGGattClient::charWritePrepareCB(Gap::Handle_t connHandle,
Andrea Palmieri 229:9981f62cdb1a 618 uint8_t event_data_length,
Andrea Palmieri 229:9981f62cdb1a 619 uint16_t attribute_handle,
Andrea Palmieri 229:9981f62cdb1a 620 uint16_t offset,
Andrea Palmieri 229:9981f62cdb1a 621 uint8_t *part_attr_value)
Andrea Palmieri 229:9981f62cdb1a 622 {
Andrea Palmieri 229:9981f62cdb1a 623 /* avoid compiler warnings about unused variables */
Andrea Palmieri 229:9981f62cdb1a 624 (void)connHandle;
Andrea Palmieri 229:9981f62cdb1a 625
Andrea Palmieri 229:9981f62cdb1a 626 // Update the write response params
Andrea Palmieri 229:9981f62cdb1a 627 writeCBParams.handle = attribute_handle;
Andrea Palmieri 229:9981f62cdb1a 628 writeCBParams.offset = offset;
Andrea Palmieri 229:9981f62cdb1a 629 writeCBParams.len = event_data_length-4; //(?)
Andrea Palmieri 229:9981f62cdb1a 630 writeCBParams.data = part_attr_value;
Andrea Palmieri 229:9981f62cdb1a 631
Andrea Palmieri 229:9981f62cdb1a 632 BlueNRGGattClient::getInstance().processWriteResponse(&writeCBParams);
Andrea Palmieri 229:9981f62cdb1a 633 }
Andrea Palmieri 229:9981f62cdb1a 634
Andrea Palmieri 229:9981f62cdb1a 635 void BlueNRGGattClient::charWriteExecCB(Gap::Handle_t connHandle,
Andrea Palmieri 229:9981f62cdb1a 636 uint8_t event_data_length)
Andrea Palmieri 229:9981f62cdb1a 637 {
Andrea Palmieri 229:9981f62cdb1a 638 /* avoid compiler warnings about unused variables */
Andrea Palmieri 229:9981f62cdb1a 639 (void)event_data_length;
Andrea Palmieri 229:9981f62cdb1a 640
Andrea Palmieri 229:9981f62cdb1a 641 writeCBParams.connHandle = connHandle;
Andrea Palmieri 229:9981f62cdb1a 642
Andrea Palmieri 229:9981f62cdb1a 643 BlueNRGGattClient::getInstance().processWriteResponse(&writeCBParams);
Andrea Palmieri 229:9981f62cdb1a 644 }
Andrea Palmieri 229:9981f62cdb1a 645
Andrea Palmieri 229:9981f62cdb1a 646 ble_error_t BlueNRGGattClient::write(GattClient::WriteOp_t cmd,
Andrea Palmieri 229:9981f62cdb1a 647 Gap::Handle_t connHandle,
Andrea Palmieri 229:9981f62cdb1a 648 GattAttribute::Handle_t attributeHandle,
Andrea Palmieri 229:9981f62cdb1a 649 size_t length,
Andrea Palmieri 229:9981f62cdb1a 650 const uint8_t *value) const
Andrea Palmieri 229:9981f62cdb1a 651 {
Andrea Palmieri 229:9981f62cdb1a 652 /* avoid compiler warnings about unused variables */
Andrea Palmieri 229:9981f62cdb1a 653 (void)cmd;
Andrea Palmieri 229:9981f62cdb1a 654
Andrea Palmieri 229:9981f62cdb1a 655 tBleStatus ret;
Andrea Palmieri 229:9981f62cdb1a 656
Andrea Palmieri 229:9981f62cdb1a 657 BlueNRGGattClient *gattc = const_cast<BlueNRGGattClient*>(this);
Andrea Palmieri 229:9981f62cdb1a 658
Andrea Palmieri 229:9981f62cdb1a 659 // We save the write response params (used by the callback) because
Andrea Palmieri 229:9981f62cdb1a 660 // when the aci_gatt_write_charac_value() is used the only event received is the EVT_BLUE_GATT_PROCEDURE_COMPLETE
Andrea Palmieri 229:9981f62cdb1a 661 gattc->writeCBParams.connHandle = connHandle;
Andrea Palmieri 229:9981f62cdb1a 662 gattc->writeCBParams.writeOp = GattWriteCallbackParams::OP_WRITE_CMD;
Andrea Palmieri 229:9981f62cdb1a 663 gattc->writeCBParams.handle = attributeHandle;
Andrea Palmieri 229:9981f62cdb1a 664 gattc->writeCBParams.offset = 0;
Andrea Palmieri 229:9981f62cdb1a 665 gattc->writeCBParams.len = length;
Andrea Palmieri 229:9981f62cdb1a 666 gattc->writeCBParams.data = value;
Andrea Palmieri 229:9981f62cdb1a 667
Andrea Palmieri 229:9981f62cdb1a 668 ret = aci_gatt_write_charac_value(connHandle, attributeHandle, length, const_cast<uint8_t *>(value));
Andrea Palmieri 229:9981f62cdb1a 669 //ret = aci_gatt_write_charac_reliable(connHandle, attributeHandle, 0, length, const_cast<uint8_t *>(value));
Andrea Palmieri 229:9981f62cdb1a 670
Andrea Palmieri 229:9981f62cdb1a 671 if (ret == BLE_STATUS_SUCCESS) {
Andrea Palmieri 229:9981f62cdb1a 672 gattc->_currentState = GATT_WRITE_CHAR;
Andrea Palmieri 229:9981f62cdb1a 673 return BLE_ERROR_NONE;
Andrea Palmieri 229:9981f62cdb1a 674 }
Andrea Palmieri 229:9981f62cdb1a 675 switch (ret) {
Andrea Palmieri 229:9981f62cdb1a 676 case BLE_STATUS_BUSY:
Andrea Palmieri 229:9981f62cdb1a 677 return BLE_STACK_BUSY;
Andrea Palmieri 229:9981f62cdb1a 678 default:
Andrea Palmieri 229:9981f62cdb1a 679 return BLE_ERROR_INVALID_STATE;
Andrea Palmieri 229:9981f62cdb1a 680 }
Andrea Palmieri 229:9981f62cdb1a 681
Andrea Palmieri 229:9981f62cdb1a 682 }
Andrea Palmieri 229:9981f62cdb1a 683
Andrea Palmieri 229:9981f62cdb1a 684 void BlueNRGGattClient::discAllCharacDescCB(Gap::Handle_t connHandle,
Andrea Palmieri 229:9981f62cdb1a 685 uint8_t event_data_length,
Andrea Palmieri 229:9981f62cdb1a 686 uint8_t format,
Andrea Palmieri 229:9981f62cdb1a 687 uint8_t *handle_uuid_pair) {
Andrea Palmieri 229:9981f62cdb1a 688 GattAttribute::Handle_t attHandle;
Andrea Palmieri 229:9981f62cdb1a 689 UUID uuid;
Andrea Palmieri 229:9981f62cdb1a 690 uint8_t i, numCharacDesc, offset, handle_uuid_length;
Andrea Palmieri 229:9981f62cdb1a 691
Andrea Palmieri 229:9981f62cdb1a 692 handle_uuid_length = 4; //Handle + UUID_16
Andrea Palmieri 229:9981f62cdb1a 693 if (format == 2)
Andrea Palmieri 229:9981f62cdb1a 694 handle_uuid_length = 18; //Handle + UUID_128
Andrea Palmieri 229:9981f62cdb1a 695
Andrea Palmieri 229:9981f62cdb1a 696 numCharacDesc = (event_data_length - 1) / handle_uuid_length;
Andrea Palmieri 229:9981f62cdb1a 697
Andrea Palmieri 229:9981f62cdb1a 698 offset = 0;
Andrea Palmieri 229:9981f62cdb1a 699
Andrea Palmieri 229:9981f62cdb1a 700 for (i=0; i<numCharacDesc; i++) {
Andrea Palmieri 229:9981f62cdb1a 701 attHandle = handle_uuid_pair[offset];
Andrea Palmieri 229:9981f62cdb1a 702
Andrea Palmieri 229:9981f62cdb1a 703 // UUID Type
Andrea Palmieri 229:9981f62cdb1a 704 if (handle_uuid_length == 4) {
Andrea Palmieri 229:9981f62cdb1a 705
Andrea Palmieri 229:9981f62cdb1a 706 PRINTF("UUID_TYPE_16\n\r");
Andrea Palmieri 229:9981f62cdb1a 707 uuid = handle_uuid_pair[offset+3]<<8|handle_uuid_pair[offset+2];
Andrea Palmieri 229:9981f62cdb1a 708 PRINTF("D UUID-%X attHandle=%u\r\n", uuid.getShortUUID(), attHandle);
Andrea Palmieri 229:9981f62cdb1a 709
Andrea Palmieri 229:9981f62cdb1a 710 } else {
Andrea Palmieri 229:9981f62cdb1a 711
Andrea Palmieri 229:9981f62cdb1a 712 PRINTF("UUID_TYPE_128\n\r");
Andrea Palmieri 229:9981f62cdb1a 713 uuid.setupLong(handle_uuid_pair+offset+2, UUID::LSB);
Andrea Palmieri 229:9981f62cdb1a 714 #ifdef DEBUG
Andrea Palmieri 229:9981f62cdb1a 715 PRINTF("D UUID-");
Andrea Palmieri 229:9981f62cdb1a 716 const uint8_t *longUUIDBytes = uuid.getBaseUUID();
Andrea Palmieri 229:9981f62cdb1a 717 for (unsigned j = 0; j < UUID::LENGTH_OF_LONG_UUID; j++) {
Andrea Palmieri 229:9981f62cdb1a 718 PRINTF("%02x", longUUIDBytes[j]);
Andrea Palmieri 229:9981f62cdb1a 719 }
Andrea Palmieri 229:9981f62cdb1a 720 #endif
Andrea Palmieri 229:9981f62cdb1a 721 }
Andrea Palmieri 229:9981f62cdb1a 722
Andrea Palmieri 229:9981f62cdb1a 723 if(charDescDiscoveryCallback != NULL) {
Andrea Palmieri 229:9981f62cdb1a 724 CharacteristicDescriptorDiscovery::DiscoveryCallbackParams_t params = {
Andrea Palmieri 229:9981f62cdb1a 725 _characteristic,
Andrea Palmieri 229:9981f62cdb1a 726 DiscoveredCharacteristicDescriptor(
Andrea Palmieri 229:9981f62cdb1a 727 _characteristic.getGattClient(),
Andrea Palmieri 229:9981f62cdb1a 728 connHandle,
Andrea Palmieri 229:9981f62cdb1a 729 attHandle,
Andrea Palmieri 229:9981f62cdb1a 730 uuid
Andrea Palmieri 229:9981f62cdb1a 731 )
Andrea Palmieri 229:9981f62cdb1a 732 };
Andrea Palmieri 229:9981f62cdb1a 733 charDescDiscoveryCallback(&params);
Andrea Palmieri 229:9981f62cdb1a 734 }
Andrea Palmieri 229:9981f62cdb1a 735
Andrea Palmieri 229:9981f62cdb1a 736 _numCharDesc++;
Andrea Palmieri 229:9981f62cdb1a 737
Andrea Palmieri 229:9981f62cdb1a 738 offset += handle_uuid_length;
Andrea Palmieri 229:9981f62cdb1a 739 }
Andrea Palmieri 229:9981f62cdb1a 740
Andrea Palmieri 229:9981f62cdb1a 741 if(charDescTerminationCallback != NULL) {
Andrea Palmieri 229:9981f62cdb1a 742 CharacteristicDescriptorDiscovery::TerminationCallbackParams_t params = {
Andrea Palmieri 229:9981f62cdb1a 743 _characteristic,
Andrea Palmieri 229:9981f62cdb1a 744 BLE_ERROR_NONE
Andrea Palmieri 229:9981f62cdb1a 745 };
Andrea Palmieri 229:9981f62cdb1a 746 charDescTerminationCallback(&params);
Andrea Palmieri 229:9981f62cdb1a 747 }
Andrea Palmieri 229:9981f62cdb1a 748
Andrea Palmieri 229:9981f62cdb1a 749 }
Andrea Palmieri 229:9981f62cdb1a 750
Andrea Palmieri 229:9981f62cdb1a 751 ble_error_t BlueNRGGattClient::discoverCharacteristicDescriptors(
Andrea Palmieri 229:9981f62cdb1a 752 const DiscoveredCharacteristic& characteristic,
Andrea Palmieri 229:9981f62cdb1a 753 const CharacteristicDescriptorDiscovery::DiscoveryCallback_t& discoveryCallback,
Andrea Palmieri 229:9981f62cdb1a 754 const CharacteristicDescriptorDiscovery::TerminationCallback_t& terminationCallback) {
Andrea Palmieri 229:9981f62cdb1a 755
Andrea Palmieri 229:9981f62cdb1a 756 tBleStatus ret;
Andrea Palmieri 229:9981f62cdb1a 757
Andrea Palmieri 229:9981f62cdb1a 758 if(_currentState != GATT_IDLE) {
Andrea Palmieri 229:9981f62cdb1a 759 return BLE_ERROR_OPERATION_NOT_PERMITTED;
Andrea Palmieri 229:9981f62cdb1a 760 }
Andrea Palmieri 229:9981f62cdb1a 761
Andrea Palmieri 229:9981f62cdb1a 762 charDescDiscoveryCallback = discoveryCallback;
Andrea Palmieri 229:9981f62cdb1a 763 charDescTerminationCallback = terminationCallback;
Andrea Palmieri 229:9981f62cdb1a 764
Andrea Palmieri 229:9981f62cdb1a 765 Gap::Handle_t connHandle = characteristic.getConnectionHandle();
Andrea Palmieri 229:9981f62cdb1a 766 GattAttribute::Handle_t valueHandle = characteristic.getValueHandle();
Andrea Palmieri 229:9981f62cdb1a 767 GattAttribute::Handle_t lastHandle = characteristic.getLastHandle();
Andrea Palmieri 229:9981f62cdb1a 768
Andrea Palmieri 229:9981f62cdb1a 769 ret = aci_gatt_disc_all_charac_descriptors(connHandle, valueHandle, lastHandle);
Andrea Palmieri 229:9981f62cdb1a 770
Andrea Palmieri 229:9981f62cdb1a 771 if (ret == BLE_STATUS_SUCCESS) {
Andrea Palmieri 229:9981f62cdb1a 772 _currentState = GATT_CHAR_DESC_DISCOVERY;
Andrea Palmieri 229:9981f62cdb1a 773 _characteristic = characteristic;
Andrea Palmieri 229:9981f62cdb1a 774 return BLE_ERROR_NONE;
Andrea Palmieri 229:9981f62cdb1a 775 }
Andrea Palmieri 229:9981f62cdb1a 776 switch (ret) {
Andrea Palmieri 229:9981f62cdb1a 777 case BLE_STATUS_INVALID_PARAMS:
Andrea Palmieri 229:9981f62cdb1a 778 return BLE_ERROR_INVALID_PARAM;
Andrea Palmieri 229:9981f62cdb1a 779 default:
Andrea Palmieri 229:9981f62cdb1a 780 return BLE_ERROR_OPERATION_NOT_PERMITTED;
Andrea Palmieri 229:9981f62cdb1a 781 }
Andrea Palmieri 229:9981f62cdb1a 782 }
Andrea Palmieri 229:9981f62cdb1a 783
Andrea Palmieri 229:9981f62cdb1a 784 /**************************************************************************/
Andrea Palmieri 229:9981f62cdb1a 785 /*!
Andrea Palmieri 229:9981f62cdb1a 786 @brief Clear BlueNRGGattServer's state.
Andrea Palmieri 229:9981f62cdb1a 787
Andrea Palmieri 229:9981f62cdb1a 788 @returns ble_error_t
Andrea Palmieri 229:9981f62cdb1a 789
Andrea Palmieri 229:9981f62cdb1a 790 @retval BLE_ERROR_NONE
Andrea Palmieri 229:9981f62cdb1a 791 Everything executed properly
Andrea Palmieri 229:9981f62cdb1a 792 */
Andrea Palmieri 229:9981f62cdb1a 793 /**************************************************************************/
Andrea Palmieri 229:9981f62cdb1a 794 ble_error_t BlueNRGGattClient::reset(void) {
Andrea Palmieri 229:9981f62cdb1a 795 /* Clear all state that is from the parent, including private members */
Andrea Palmieri 229:9981f62cdb1a 796 if (GattClient::reset() != BLE_ERROR_NONE) {
Andrea Palmieri 229:9981f62cdb1a 797 return BLE_ERROR_INVALID_STATE;
Andrea Palmieri 229:9981f62cdb1a 798 }
Andrea Palmieri 229:9981f62cdb1a 799
Andrea Palmieri 229:9981f62cdb1a 800 _currentState = GATT_IDLE;
Andrea Palmieri 229:9981f62cdb1a 801 _matchingServiceUUID = BLE_UUID_UNKNOWN;
Andrea Palmieri 229:9981f62cdb1a 802 _matchingCharacteristicUUIDIn = BLE_UUID_UNKNOWN;
Andrea Palmieri 229:9981f62cdb1a 803
Andrea Palmieri 229:9981f62cdb1a 804 _numServices = 0;
Andrea Palmieri 229:9981f62cdb1a 805 _servIndex = 0;
Andrea Palmieri 229:9981f62cdb1a 806 _numChars = 0;
Andrea Palmieri 229:9981f62cdb1a 807 _numCharDesc = 0;
Andrea Palmieri 229:9981f62cdb1a 808
Andrea Palmieri 229:9981f62cdb1a 809 /* Clear class members */
Andrea Palmieri 229:9981f62cdb1a 810 memset(discoveredService, 0, sizeof(discoveredService));
Andrea Palmieri 229:9981f62cdb1a 811 memset(discoveredChar, 0, sizeof(discoveredChar));
Andrea Palmieri 229:9981f62cdb1a 812
Andrea Palmieri 229:9981f62cdb1a 813 return BLE_ERROR_NONE;
Andrea Palmieri 229:9981f62cdb1a 814 }
Andrea Palmieri 229:9981f62cdb1a 815