This is an example of BLE GATT Client, which receives broadcast data from BLE_Server_BME280 ( a GATT server) , then transfers values up to mbed Device Connector (cloud).

Please refer details about BLEClient_mbedDevConn below. https://github.com/soramame21/BLEClient_mbedDevConn

The location of required BLE GATT server, BLE_Server_BME280, is at here. https://developer.mbed.org/users/edamame22/code/BLE_Server_BME280/

Committer:
edamame22
Date:
Thu Apr 13 04:48:11 2017 +0000
Revision:
0:29983394c6b6
Initial commit

Who changed what in which revision?

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