Fork of ble-x-nucleo-idb0xa1 with changes required by BleStarMbed

Dependents:   ble-star-mbed

Committer:
lorevee
Date:
Tue Feb 20 11:07:16 2018 +0000
Revision:
0:ac0b0725c6fa
Initial commit

Who changed what in which revision?

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