nrf52-dk

Committer:
mamont090671
Date:
Fri Jun 05 10:49:10 2020 +0000
Revision:
0:70ce6da7a141
nrf52840

Who changed what in which revision?

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