BLE_API wrapper library for STMicroelectronics' BlueNRG Bluetooth Low Energy expansion board shield (Component)

Dependents:   Nucleo_Zumo_BLE_IDB04A1 contest_IOT5 contest_IOT6 contest_IOT_10 ... more

Fork of X_NUCLEO_IDB0XA1 by ST Expansion SW Team

Arduino Connector Compatibility Warning

X-NUCLEO-IDB04A1 and X-NUCLEO-IDB05A1 are Arduino compatible with an exception: instead of using pin D13 for the SPI clock, they use pin D3. The default configuration for this library is having the SPI clock on pin D3.

To be fully Arduino compatible, X-NUCLEO-IDB04A1 and X-NUCLEO-IDB05A1 need a small HW patch.

For X-NUCLEO-IDB04A1 this patch consists in removing zero resistor R10 and instead soldering zero resistor R11. For X-NUCLEO-IDB05A1 this patch consists in removing zero resistor R4 and instead soldering zero resistor R6.

In case you patch your board, then you also have to configure this library to use pin D13 to drive the SPI clock (see macro IDB0XA1_D13_PATCH in file x_nucleo_idb0xa1_targets.h).

If you use pin D13 for the SPI clock, please be aware that on STM32 Nucleo boards you may not drive the LED, otherwise you will get a conflict: the LED on STM32 Nucleo boards is connected to pin D13.

Referring to the current list of tested platforms (see X-NUCLEO-IDB04A1 and X-NUCLEO-IDB05A1 pages), the patch is required by ST-Nucleo-F103RB; ST-Nucleo-F302R8; ST-Nucleo-F411RE; and ST-Nucleo-F446RE.

Committer:
Vincent Coubard
Date:
Thu Sep 15 10:51:24 2016 +0100
Branch:
a38223e17a624c1ac4d9e2589f363d2e202f12a5
Revision:
262:a3460768f3b7
Parent:
261:16cdf278f70a
Child:
263:8516afb5e29c
Sync with a38223e17a624c1ac4d9e2589f363d2e202f12a5

2016-07-08 18:04:01+01:00: Vincent Coubard
Fix characteristic descriptor discovery

Who changed what in which revision?

UserRevisionLine numberNew contents of line
Wolfgang Betz 130:770ce14d3d15 1 /* mbed Microcontroller Library
Wolfgang Betz 130:770ce14d3d15 2 * Copyright (c) 2006-2013 ARM Limited
Wolfgang Betz 130:770ce14d3d15 3 *
Wolfgang Betz 130:770ce14d3d15 4 * Licensed under the Apache License, Version 2.0 (the "License");
Wolfgang Betz 130:770ce14d3d15 5 * you may not use this file except in compliance with the License.
Wolfgang Betz 130:770ce14d3d15 6 * You may obtain a copy of the License at
Wolfgang Betz 130:770ce14d3d15 7 *
Wolfgang Betz 130:770ce14d3d15 8 * http://www.apache.org/licenses/LICENSE-2.0
Wolfgang Betz 130:770ce14d3d15 9 *
Wolfgang Betz 130:770ce14d3d15 10 * Unless required by applicable law or agreed to in writing, software
Wolfgang Betz 130:770ce14d3d15 11 * distributed under the License is distributed on an "AS IS" BASIS,
Wolfgang Betz 130:770ce14d3d15 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
Wolfgang Betz 130:770ce14d3d15 13 * See the License for the specific language governing permissions and
Wolfgang Betz 130:770ce14d3d15 14 * limitations under the License.
Wolfgang Betz 130:770ce14d3d15 15 */
Wolfgang Betz 130:770ce14d3d15 16 /**
Wolfgang Betz 130:770ce14d3d15 17 ******************************************************************************
Vincent Coubard 258:e5ef65120b06 18 * @file BlueNRGGattServer.cpp
Wolfgang Betz 130:770ce14d3d15 19 * @author STMicroelectronics
Wolfgang Betz 130:770ce14d3d15 20 * @brief Implementation of BlueNRG BLE_API GattServer Class
Wolfgang Betz 130:770ce14d3d15 21 ******************************************************************************
Wolfgang Betz 130:770ce14d3d15 22 * @copy
Wolfgang Betz 130:770ce14d3d15 23 *
Wolfgang Betz 130:770ce14d3d15 24 * THE PRESENT FIRMWARE WHICH IS FOR GUIDANCE ONLY AIMS AT PROVIDING CUSTOMERS
Wolfgang Betz 130:770ce14d3d15 25 * WITH CODING INFORMATION REGARDING THEIR PRODUCTS IN ORDER FOR THEM TO SAVE
Wolfgang Betz 130:770ce14d3d15 26 * TIME. AS A RESULT, STMICROELECTRONICS SHALL NOT BE HELD LIABLE FOR ANY
Wolfgang Betz 130:770ce14d3d15 27 * DIRECT, INDIRECT OR CONSEQUENTIAL DAMAGES WITH RESPECT TO ANY CLAIMS ARISING
Wolfgang Betz 130:770ce14d3d15 28 * FROM THE CONTENT OF SUCH FIRMWARE AND/OR THE USE MADE BY CUSTOMERS OF THE
Wolfgang Betz 130:770ce14d3d15 29 * CODING INFORMATION CONTAINED HEREIN IN CONNECTION WITH THEIR PRODUCTS.
Wolfgang Betz 130:770ce14d3d15 30 *
Wolfgang Betz 130:770ce14d3d15 31 * <h2><center>&copy; COPYRIGHT 2013 STMicroelectronics</center></h2>
Andrea Palmieri 229:9981f62cdb1a 32 */
Vincent Coubard 258:e5ef65120b06 33
Wolfgang Betz 130:770ce14d3d15 34 /** @defgroup BlueNRGGATTSERVER
Wolfgang Betz 130:770ce14d3d15 35 * @brief BlueNRG BLE_API GattServer Adaptation
Wolfgang Betz 130:770ce14d3d15 36 * @{
Wolfgang Betz 130:770ce14d3d15 37 */
Vincent Coubard 258:e5ef65120b06 38
Wolfgang Betz 130:770ce14d3d15 39 #include "BlueNRGGattServer.h"
Vincent Coubard 253:9665a6f8bbdb 40 #include "mbed-drivers/mbed.h"
Wolfgang Betz 130:770ce14d3d15 41 #include "BlueNRGGap.h"
Wolfgang Betz 130:770ce14d3d15 42 #include "Utils.h"
Wolfgang Betz 132:51056160fa4a 43 #include "debug.h"
Wolfgang Betz 130:770ce14d3d15 44
Wolfgang Betz 130:770ce14d3d15 45 /**************************************************************************/
Wolfgang Betz 130:770ce14d3d15 46 /*!
Wolfgang Betz 130:770ce14d3d15 47 @brief Adds a new service to the GATT table on the peripheral
Wolfgang Betz 130:770ce14d3d15 48
Wolfgang Betz 130:770ce14d3d15 49 @params[in] service
Wolfgang Betz 130:770ce14d3d15 50 Pointer to instance of the Gatt Server to add
Vincent Coubard 258:e5ef65120b06 51
Wolfgang Betz 130:770ce14d3d15 52 @returns ble_error_t
Wolfgang Betz 130:770ce14d3d15 53
Wolfgang Betz 130:770ce14d3d15 54 @retval BLE_ERROR_NONE
Wolfgang Betz 130:770ce14d3d15 55 Everything executed properly
Wolfgang Betz 130:770ce14d3d15 56
Wolfgang Betz 130:770ce14d3d15 57 @section EXAMPLE
Wolfgang Betz 130:770ce14d3d15 58
Wolfgang Betz 130:770ce14d3d15 59 @code
Wolfgang Betz 130:770ce14d3d15 60
Wolfgang Betz 130:770ce14d3d15 61 @endcode
Wolfgang Betz 130:770ce14d3d15 62 */
Wolfgang Betz 130:770ce14d3d15 63 /**************************************************************************/
Wolfgang Betz 130:770ce14d3d15 64 ble_error_t BlueNRGGattServer::addService(GattService &service)
Wolfgang Betz 130:770ce14d3d15 65 {
Wolfgang Betz 130:770ce14d3d15 66 /* ToDo: Make sure we don't overflow the array, etc. */
Wolfgang Betz 130:770ce14d3d15 67 /* ToDo: Make sure this service UUID doesn't already exist (?) */
Wolfgang Betz 130:770ce14d3d15 68 /* ToDo: Basic validation */
Vincent Coubard 258:e5ef65120b06 69
Wolfgang Betz 130:770ce14d3d15 70 tBleStatus ret;
Wolfgang Betz 130:770ce14d3d15 71 uint8_t type;
Wolfgang Betz 130:770ce14d3d15 72 uint16_t short_uuid;
Wolfgang Betz 130:770ce14d3d15 73 uint8_t primary_short_uuid[2];
Wolfgang Betz 130:770ce14d3d15 74 uint8_t primary_base_uuid[16];
Wolfgang Betz 130:770ce14d3d15 75 uint8_t char_base_uuid[16];
Wolfgang Betz 130:770ce14d3d15 76 const uint8_t *base_uuid;
Wolfgang Betz 130:770ce14d3d15 77 const uint8_t *base_char_uuid;
Vincent Coubard 258:e5ef65120b06 78
Vincent Coubard 259:323f588e5f57 79 uint8_t charsCount = service.getCharacteristicCount();
Vincent Coubard 259:323f588e5f57 80 const uint8_t available_characteristics = BLE_TOTAL_CHARACTERISTICS - characteristicCount;
Vincent Coubard 259:323f588e5f57 81
Vincent Coubard 259:323f588e5f57 82 // check that there is enough characteristics left in the
Vincent Coubard 259:323f588e5f57 83 // characteristic array.
Vincent Coubard 259:323f588e5f57 84 if (charsCount > available_characteristics) {
Vincent Coubard 259:323f588e5f57 85 PRINTF("charCount = %u and characteristicCount = %u\r\n", charsCount, available_characteristics);
Vincent Coubard 259:323f588e5f57 86 return BLE_ERROR_NO_MEM;
Vincent Coubard 259:323f588e5f57 87 }
Vincent Coubard 259:323f588e5f57 88
Vincent Coubard 259:323f588e5f57 89 const uint16_t maxAttrRecords = computeAttributesRecord(service);
Wolfgang Betz 130:770ce14d3d15 90
Wolfgang Betz 130:770ce14d3d15 91 type = (service.getUUID()).shortOrLong();
Wolfgang Betz 132:51056160fa4a 92 PRINTF("AddService(): Type:%d\n\r", type);
Vincent Coubard 258:e5ef65120b06 93
Wolfgang Betz 130:770ce14d3d15 94 /* Add the service to the BlueNRG */
Wolfgang Betz 130:770ce14d3d15 95 short_uuid = (service.getUUID()).getShortUUID();
Wolfgang Betz 130:770ce14d3d15 96 STORE_LE_16(primary_short_uuid, short_uuid);
Vincent Coubard 258:e5ef65120b06 97
Wolfgang Betz 130:770ce14d3d15 98 if(type==UUID::UUID_TYPE_LONG) {
Vincent Coubard 258:e5ef65120b06 99 base_uuid = (service.getUUID()).getBaseUUID();
Vincent Coubard 258:e5ef65120b06 100
Andrea Palmieri 207:b9df918d6d5a 101 COPY_UUID_128(primary_base_uuid, base_uuid[15],base_uuid[14],primary_short_uuid[1],primary_short_uuid[0],base_uuid[11],base_uuid[10],base_uuid[9],base_uuid[8],base_uuid[7],base_uuid[6],base_uuid[5],base_uuid[4],base_uuid[3],base_uuid[2],base_uuid[1],base_uuid[0]);
Wolfgang Betz 130:770ce14d3d15 102 }
Wolfgang Betz 130:770ce14d3d15 103
Wolfgang Betz 130:770ce14d3d15 104 if(type==UUID::UUID_TYPE_SHORT) {
Wolfgang Betz 130:770ce14d3d15 105 ret = aci_gatt_add_serv(UUID_TYPE_16,
Wolfgang Betz 130:770ce14d3d15 106 primary_short_uuid,
Wolfgang Betz 130:770ce14d3d15 107 PRIMARY_SERVICE,
Wolfgang Betz 130:770ce14d3d15 108 maxAttrRecords/*7*/,
Wolfgang Betz 130:770ce14d3d15 109 &servHandle);
Vincent Coubard 259:323f588e5f57 110 PRINTF("aci_gatt_add_serv UUID_TYPE_SHORT ret=%d\n\r", ret);
Vincent Coubard 259:323f588e5f57 111
Wolfgang Betz 130:770ce14d3d15 112 }
Wolfgang Betz 130:770ce14d3d15 113 else if(type==UUID::UUID_TYPE_LONG) {
Wolfgang Betz 130:770ce14d3d15 114 ret = aci_gatt_add_serv(UUID_TYPE_128,
Wolfgang Betz 130:770ce14d3d15 115 primary_base_uuid,
Wolfgang Betz 130:770ce14d3d15 116 PRIMARY_SERVICE,
Wolfgang Betz 130:770ce14d3d15 117 maxAttrRecords/*7*/,
Wolfgang Betz 130:770ce14d3d15 118 &servHandle);
Wolfgang Betz 132:51056160fa4a 119 PRINTF("aci_gatt_add_serv UUID_TYPE_LONG ret=%d\n\r", ret);
Wolfgang Betz 130:770ce14d3d15 120 }
Vincent Coubard 258:e5ef65120b06 121
Vincent Coubard 259:323f588e5f57 122 switch (ret) {
Vincent Coubard 259:323f588e5f57 123 case BLE_STATUS_SUCCESS:
Vincent Coubard 259:323f588e5f57 124 break;
Vincent Coubard 259:323f588e5f57 125
Vincent Coubard 259:323f588e5f57 126 case BLE_STATUS_INVALID_PARAMETER:
Vincent Coubard 259:323f588e5f57 127 return BLE_ERROR_INVALID_PARAM;
Vincent Coubard 259:323f588e5f57 128
Vincent Coubard 259:323f588e5f57 129 case BLE_STATUS_OUT_OF_HANDLE:
Vincent Coubard 259:323f588e5f57 130 case BLE_STATUS_INSUFFICIENT_RESOURCES:
Vincent Coubard 259:323f588e5f57 131 case ERR_UNSPECIFIED_ERROR:
Vincent Coubard 259:323f588e5f57 132 return BLE_ERROR_NO_MEM;
Vincent Coubard 259:323f588e5f57 133
Vincent Coubard 259:323f588e5f57 134 case BLE_STATUS_ERROR:
Vincent Coubard 259:323f588e5f57 135 default:
Vincent Coubard 259:323f588e5f57 136 return BLE_ERROR_INTERNAL_STACK_FAILURE;
Vincent Coubard 259:323f588e5f57 137 }
Vincent Coubard 259:323f588e5f57 138
Vincent Coubard 259:323f588e5f57 139
Vincent Coubard 259:323f588e5f57 140
Wolfgang Betz 130:770ce14d3d15 141 service.setHandle(servHandle);
Wolfgang Betz 130:770ce14d3d15 142 //serviceHandleVector.push_back(servHandle);
Wolfgang Betz 132:51056160fa4a 143 PRINTF("added servHandle handle =%u\n\r", servHandle);
Wolfgang Betz 130:770ce14d3d15 144 uint16_t bleCharacteristic;
Vincent Coubard 258:e5ef65120b06 145
Wolfgang Betz 130:770ce14d3d15 146 //iterate to include all characteristics
Wolfgang Betz 130:770ce14d3d15 147 for (uint8_t i = 0; i < charsCount; i++) {
Wolfgang Betz 130:770ce14d3d15 148 GattCharacteristic *p_char = service.getCharacteristic(i);
Andrea Palmieri 229:9981f62cdb1a 149 uint16_t char_uuid = (p_char->getValueAttribute().getUUID()).getShortUUID();
Andrea Palmieri 229:9981f62cdb1a 150
Wolfgang Betz 130:770ce14d3d15 151 uint8_t int_8_uuid[2];
Wolfgang Betz 130:770ce14d3d15 152 STORE_LE_16(int_8_uuid, char_uuid);
Andrea Palmieri 229:9981f62cdb1a 153
Andrea Palmieri 229:9981f62cdb1a 154 type = (p_char->getValueAttribute().getUUID()).shortOrLong();
Andrea Palmieri 229:9981f62cdb1a 155
Wolfgang Betz 130:770ce14d3d15 156 if(type==UUID::UUID_TYPE_LONG) {
Wolfgang Betz 130:770ce14d3d15 157 base_char_uuid = (p_char->getValueAttribute().getUUID()).getBaseUUID();
Andrea Palmieri 229:9981f62cdb1a 158 #ifdef DEBUG
Andrea Palmieri 229:9981f62cdb1a 159 for(uint8_t j=0; j<16; j++) {
Andrea Palmieri 229:9981f62cdb1a 160 PRINTF("base_char_uuid[%d] 0x%02x ", j, base_char_uuid[j]);
Andrea Palmieri 229:9981f62cdb1a 161 }
Andrea Palmieri 229:9981f62cdb1a 162 PRINTF("\n\r");
Andrea Palmieri 229:9981f62cdb1a 163 #endif
Andrea Palmieri 207:b9df918d6d5a 164 COPY_UUID_128(char_base_uuid,base_char_uuid[15],base_char_uuid[14],int_8_uuid[1],int_8_uuid[0],base_char_uuid[11],base_char_uuid[10],base_char_uuid[9],base_char_uuid[8],base_char_uuid[7],base_char_uuid[6],base_char_uuid[5],base_char_uuid[4],base_char_uuid[3],base_char_uuid[2],base_char_uuid[1],base_char_uuid[0]);
Wolfgang Betz 130:770ce14d3d15 165 }
Vincent Coubard 258:e5ef65120b06 166
Wolfgang Betz 132:51056160fa4a 167 PRINTF("Char Properties 0x%x\n\r", p_char->getProperties());
Wolfgang Betz 130:770ce14d3d15 168 /*
Wolfgang Betz 130:770ce14d3d15 169 * Gatt_Evt_Mask -> HardCoded (0)
Wolfgang Betz 130:770ce14d3d15 170 * Encryption_Key_Size -> Hardcoded (16)
Wolfgang Betz 130:770ce14d3d15 171 * isVariable (variable length value field) -> Hardcoded (1)
Wolfgang Betz 130:770ce14d3d15 172 */
Wolfgang Betz 130:770ce14d3d15 173 uint8_t Gatt_Evt_Mask = 0x0;
Wolfgang Betz 130:770ce14d3d15 174
Wolfgang Betz 130:770ce14d3d15 175 if((p_char->getProperties() &
Wolfgang Betz 130:770ce14d3d15 176 (GattCharacteristic::BLE_GATT_CHAR_PROPERTIES_WRITE_WITHOUT_RESPONSE|
Wolfgang Betz 130:770ce14d3d15 177 GattCharacteristic::BLE_GATT_CHAR_PROPERTIES_WRITE))) {
Wolfgang Betz 132:51056160fa4a 178 PRINTF("Setting up Gatt GATT_NOTIFY_ATTRIBUTE_WRITE Mask\n\r");
Vincent Coubard 260:e93cbde933ce 179 Gatt_Evt_Mask = Gatt_Evt_Mask | GATT_NOTIFY_ATTRIBUTE_WRITE /* | GATT_NOTIFY_WRITE_REQ_AND_WAIT_FOR_APPL_RESP */;
Wolfgang Betz 130:770ce14d3d15 180 }
Wolfgang Betz 130:770ce14d3d15 181 if((p_char->getProperties() &
Wolfgang Betz 130:770ce14d3d15 182 (GattCharacteristic::BLE_GATT_CHAR_PROPERTIES_READ|
Wolfgang Betz 130:770ce14d3d15 183 GattCharacteristic::BLE_GATT_CHAR_PROPERTIES_NOTIFY| GattCharacteristic::BLE_GATT_CHAR_PROPERTIES_INDICATE))) {
Wolfgang Betz 132:51056160fa4a 184 PRINTF("Setting up Gatt GATT_NOTIFY_READ_REQ_AND_WAIT_FOR_APPL_RESP Mask\n\r");
Vincent Coubard 258:e5ef65120b06 185 Gatt_Evt_Mask = Gatt_Evt_Mask | GATT_NOTIFY_READ_REQ_AND_WAIT_FOR_APPL_RESP;
Wolfgang Betz 130:770ce14d3d15 186 } //This will support also GATT_SERVER_ATTR_READ_WRITE since it will be covered by previous if() check.
Wolfgang Betz 130:770ce14d3d15 187
Wolfgang Betz 130:770ce14d3d15 188 if(type==UUID::UUID_TYPE_SHORT) {
Wolfgang Betz 130:770ce14d3d15 189 ret = aci_gatt_add_char(service.getHandle(),
Wolfgang Betz 130:770ce14d3d15 190 UUID_TYPE_16,
Wolfgang Betz 130:770ce14d3d15 191 int_8_uuid,
Wolfgang Betz 130:770ce14d3d15 192 p_char->getValueAttribute().getMaxLength() /*2*/ /*Value Length*/,
Wolfgang Betz 130:770ce14d3d15 193 p_char->getProperties(),
Wolfgang Betz 130:770ce14d3d15 194 ATTR_PERMISSION_NONE,
Wolfgang Betz 130:770ce14d3d15 195 Gatt_Evt_Mask /*Gatt_Evt_Mask*/,
Wolfgang Betz 130:770ce14d3d15 196 16 /*Encryption_Key_Size*/,
Wolfgang Betz 130:770ce14d3d15 197 1 /*isVariable*/,
Wolfgang Betz 130:770ce14d3d15 198 &bleCharacteristic);
Vincent Coubard 258:e5ef65120b06 199
Andrea Palmieri 229:9981f62cdb1a 200 PRINTF("aci_gatt_add_char UUID_TYPE_16 props=%d MaxLength=%d ret=%d\n\r",
Andrea Palmieri 229:9981f62cdb1a 201 p_char->getProperties(), p_char->getValueAttribute().getMaxLength(), ret);
Wolfgang Betz 130:770ce14d3d15 202
Wolfgang Betz 130:770ce14d3d15 203 } else if(type==UUID::UUID_TYPE_LONG) {
Wolfgang Betz 130:770ce14d3d15 204 ret = aci_gatt_add_char(service.getHandle(),
Wolfgang Betz 130:770ce14d3d15 205 UUID_TYPE_128,
Wolfgang Betz 130:770ce14d3d15 206 char_base_uuid,
Wolfgang Betz 130:770ce14d3d15 207 p_char->getValueAttribute().getMaxLength() /*2*/ /*Value Length*/,
Wolfgang Betz 130:770ce14d3d15 208 p_char->getProperties(),
Wolfgang Betz 130:770ce14d3d15 209 ATTR_PERMISSION_NONE,
Wolfgang Betz 130:770ce14d3d15 210 Gatt_Evt_Mask /*Gatt_Evt_Mask*/,
Wolfgang Betz 130:770ce14d3d15 211 16 /*Encryption_Key_Size*/,
Wolfgang Betz 130:770ce14d3d15 212 1 /*isVariable*/,
Wolfgang Betz 130:770ce14d3d15 213 &bleCharacteristic);
Vincent Coubard 258:e5ef65120b06 214
Andrea Palmieri 229:9981f62cdb1a 215 PRINTF("aci_gatt_add_char UUID_TYPE_128 props=%d MaxLength=%d ret=%d\n\r",
Andrea Palmieri 229:9981f62cdb1a 216 p_char->getProperties(), p_char->getValueAttribute().getMaxLength(), ret);
Wolfgang Betz 130:770ce14d3d15 217 }
Vincent Coubard 258:e5ef65120b06 218
Vincent Coubard 259:323f588e5f57 219 switch (ret) {
Vincent Coubard 259:323f588e5f57 220 case BLE_STATUS_SUCCESS:
Vincent Coubard 259:323f588e5f57 221 break;
Vincent Coubard 259:323f588e5f57 222
Vincent Coubard 259:323f588e5f57 223 case ERR_UNSPECIFIED_ERROR:
Vincent Coubard 259:323f588e5f57 224 case BLE_STATUS_INSUFFICIENT_RESOURCES:
Vincent Coubard 259:323f588e5f57 225 case BLE_STATUS_OUT_OF_HANDLE:
Vincent Coubard 259:323f588e5f57 226 // TODO remove characteristics and the service previously added.
Vincent Coubard 259:323f588e5f57 227 // remove service in the stack by using: Aci_Gatt_Del_Service
Vincent Coubard 259:323f588e5f57 228 // remove characteristics in the stack by using: Aci_Gatt_Del_Char
Vincent Coubard 259:323f588e5f57 229 // update service counter
Vincent Coubard 259:323f588e5f57 230 // destroy registered characteristic and updat echaracteristic counter
Vincent Coubard 259:323f588e5f57 231 return BLE_ERROR_NO_MEM;
Vincent Coubard 259:323f588e5f57 232
Vincent Coubard 259:323f588e5f57 233 case BLE_STATUS_INVALID_HANDLE:
Vincent Coubard 259:323f588e5f57 234 case BLE_STATUS_INVALID_PARAMETER:
Vincent Coubard 259:323f588e5f57 235 case BLE_STATUS_CHARAC_ALREADY_EXISTS:
Vincent Coubard 259:323f588e5f57 236 // TODO remove characteristics and the service previously added.
Vincent Coubard 259:323f588e5f57 237 // remove service in the stack by using: Aci_Gatt_Del_Service
Vincent Coubard 259:323f588e5f57 238 // remove characteristics in the stack by using: Aci_Gatt_Del_Char
Vincent Coubard 259:323f588e5f57 239 // update service counter
Vincent Coubard 259:323f588e5f57 240 // destroy registered characteristic and updat echaracteristic counter
Vincent Coubard 259:323f588e5f57 241 return BLE_ERROR_INVALID_PARAM;
Vincent Coubard 259:323f588e5f57 242
Vincent Coubard 259:323f588e5f57 243 case BLE_STATUS_ERROR:
Vincent Coubard 259:323f588e5f57 244 default:
Vincent Coubard 259:323f588e5f57 245 // TODO remove characteristics and the service previously added.
Vincent Coubard 259:323f588e5f57 246 // remove service in the stack by using: Aci_Gatt_Del_Service
Vincent Coubard 259:323f588e5f57 247 // remove characteristics in the stack by using: Aci_Gatt_Del_Char
Vincent Coubard 259:323f588e5f57 248 // update service counter
Vincent Coubard 259:323f588e5f57 249 // destroy registered characteristic and updat echaracteristic counter
Vincent Coubard 259:323f588e5f57 250 return BLE_ERROR_INTERNAL_STACK_FAILURE;
Vincent Coubard 259:323f588e5f57 251 }
Vincent Coubard 259:323f588e5f57 252
Andrea Palmieri 229:9981f62cdb1a 253 bleCharHandleMap.insert(std::pair<uint16_t, uint16_t>(bleCharacteristic, servHandle));
Vincent Coubard 258:e5ef65120b06 254
Wolfgang Betz 130:770ce14d3d15 255 p_characteristics[characteristicCount++] = p_char;
Andrea Palmieri 229:9981f62cdb1a 256 /* Set the characteristic value handle */
Andrea Palmieri 229:9981f62cdb1a 257 p_char->getValueAttribute().setHandle(bleCharacteristic+BlueNRGGattServer::CHAR_VALUE_HANDLE);
Andrea Palmieri 229:9981f62cdb1a 258 PRINTF("added bleCharacteristic (value handle =%u)\n\r", p_char->getValueAttribute().getHandle());
Wolfgang Betz 130:770ce14d3d15 259
Andrea Palmieri 202:caf4864292c1 260 if ((p_char->getValueAttribute().getValuePtr() != NULL) && (p_char->getValueAttribute().getLength() > 0)) {
Vincent Coubard 259:323f588e5f57 261 ble_error_t err = write(p_char->getValueAttribute().getHandle(),
Andrea Palmieri 229:9981f62cdb1a 262 p_char->getValueAttribute().getValuePtr(),
Andrea Palmieri 229:9981f62cdb1a 263 p_char->getValueAttribute().getLength(), false /* localOnly */);
Vincent Coubard 259:323f588e5f57 264 if (err) {
Vincent Coubard 259:323f588e5f57 265 PRINTF("ERROR HERE !!!!\r\n");
Vincent Coubard 259:323f588e5f57 266 return err;
Vincent Coubard 259:323f588e5f57 267 }
Wolfgang Betz 130:770ce14d3d15 268 }
Wolfgang Betz 130:770ce14d3d15 269
Wolfgang Betz 130:770ce14d3d15 270 // add descriptors now
Wolfgang Betz 130:770ce14d3d15 271 uint16_t descHandle = 0;
Wolfgang Betz 132:51056160fa4a 272 PRINTF("p_char->getDescriptorCount()=%d\n\r", p_char->getDescriptorCount());
Vincent Coubard 258:e5ef65120b06 273
Wolfgang Betz 130:770ce14d3d15 274 for(uint8_t descIndex=0; descIndex<p_char->getDescriptorCount(); descIndex++) {
Wolfgang Betz 130:770ce14d3d15 275 GattAttribute *descriptor = p_char->getDescriptor(descIndex);
Vincent Coubard 262:a3460768f3b7 276 uint8_t desc_uuid[16] = { 0 };
Vincent Coubard 262:a3460768f3b7 277
Vincent Coubard 262:a3460768f3b7 278
Vincent Coubard 262:a3460768f3b7 279 uint8_t desc_uuid_type = CHAR_DESC_TYPE_16_BIT;
Vincent Coubard 262:a3460768f3b7 280 STORE_LE_16(desc_uuid, descriptor->getUUID().getShortUUID());
Vincent Coubard 262:a3460768f3b7 281
Vincent Coubard 262:a3460768f3b7 282 if((descriptor->getUUID()).shortOrLong() == UUID::UUID_TYPE_LONG) {
Vincent Coubard 262:a3460768f3b7 283 desc_uuid_type = CHAR_DESC_TYPE_128_BIT;
Vincent Coubard 262:a3460768f3b7 284 const uint8_t* base_desc_uuid = descriptor->getUUID().getBaseUUID();
Vincent Coubard 262:a3460768f3b7 285
Vincent Coubard 262:a3460768f3b7 286 COPY_UUID_128(desc_uuid, base_desc_uuid[15], base_desc_uuid[14],base_desc_uuid[13],base_desc_uuid[12], base_desc_uuid[11], base_desc_uuid[10], base_desc_uuid[9], base_desc_uuid[8], base_desc_uuid[7], base_desc_uuid[6], base_desc_uuid[5], base_desc_uuid[4], base_desc_uuid[3], base_desc_uuid[2], base_desc_uuid[1], base_desc_uuid[0]);
Vincent Coubard 262:a3460768f3b7 287 }
Vincent Coubard 262:a3460768f3b7 288
Andrea Palmieri 229:9981f62cdb1a 289 ret = aci_gatt_add_char_desc(service.getHandle(),
Andrea Palmieri 229:9981f62cdb1a 290 bleCharacteristic,
Vincent Coubard 262:a3460768f3b7 291 desc_uuid_type,
Vincent Coubard 262:a3460768f3b7 292 desc_uuid,
Andrea Palmieri 229:9981f62cdb1a 293 descriptor->getMaxLength(),
Andrea Palmieri 229:9981f62cdb1a 294 descriptor->getLength(),
Andrea Palmieri 229:9981f62cdb1a 295 descriptor->getValuePtr(),
Andrea Palmieri 229:9981f62cdb1a 296 CHAR_DESC_SECURITY_PERMISSION,
Andrea Palmieri 229:9981f62cdb1a 297 CHAR_DESC_ACCESS_PERMISSION,
Andrea Palmieri 229:9981f62cdb1a 298 GATT_NOTIFY_ATTRIBUTE_WRITE,
Andrea Palmieri 229:9981f62cdb1a 299 MIN_ENCRY_KEY_SIZE,
Andrea Palmieri 229:9981f62cdb1a 300 CHAR_ATTRIBUTE_LEN_IS_FIXED,
Andrea Palmieri 229:9981f62cdb1a 301 &descHandle);
Wolfgang Betz 132:51056160fa4a 302 PRINTF("Adding Descriptor descriptor handle=%d ret=%d\n\r", descHandle, ret);
Vincent Coubard 259:323f588e5f57 303
Vincent Coubard 259:323f588e5f57 304 switch (ret) {
Vincent Coubard 259:323f588e5f57 305 case BLE_STATUS_SUCCESS:
Vincent Coubard 259:323f588e5f57 306 PRINTF("Descriptor added successfully, descriptor handle=%d\n\r", descHandle);
Vincent Coubard 259:323f588e5f57 307 descriptor->setHandle(descHandle);
Vincent Coubard 259:323f588e5f57 308 break;
Vincent Coubard 259:323f588e5f57 309
Vincent Coubard 259:323f588e5f57 310 case ERR_UNSPECIFIED_ERROR:
Vincent Coubard 259:323f588e5f57 311 case BLE_STATUS_INSUFFICIENT_RESOURCES:
Vincent Coubard 259:323f588e5f57 312 case BLE_STATUS_OUT_OF_HANDLE:
Vincent Coubard 259:323f588e5f57 313 // TODO remove characteristics and the service previously added.
Vincent Coubard 259:323f588e5f57 314 // remove service in the stack by using: Aci_Gatt_Del_Service
Vincent Coubard 259:323f588e5f57 315 // remove characteristics in the stack by using: Aci_Gatt_Del_Char
Vincent Coubard 259:323f588e5f57 316 // update service counter
Vincent Coubard 259:323f588e5f57 317 // destroy registered characteristic and updat echaracteristic counter
Vincent Coubard 259:323f588e5f57 318 return BLE_ERROR_NO_MEM;
Vincent Coubard 259:323f588e5f57 319
Vincent Coubard 259:323f588e5f57 320 case BLE_STATUS_INVALID_HANDLE:
Vincent Coubard 259:323f588e5f57 321 case BLE_STATUS_INVALID_PARAMETER:
Vincent Coubard 259:323f588e5f57 322 // TODO remove characteristics and the service previously added.
Vincent Coubard 259:323f588e5f57 323 // remove service in the stack by using: Aci_Gatt_Del_Service
Vincent Coubard 259:323f588e5f57 324 // remove characteristics in the stack by using: Aci_Gatt_Del_Char
Vincent Coubard 259:323f588e5f57 325 // update service counter
Vincent Coubard 259:323f588e5f57 326 // destroy registered characteristic and updat echaracteristic counter
Vincent Coubard 259:323f588e5f57 327 return BLE_ERROR_INVALID_PARAM;
Vincent Coubard 259:323f588e5f57 328
Vincent Coubard 259:323f588e5f57 329 case BLE_STATUS_INVALID_OPERATION:
Vincent Coubard 259:323f588e5f57 330 return BLE_ERROR_OPERATION_NOT_PERMITTED;
Vincent Coubard 259:323f588e5f57 331
Vincent Coubard 259:323f588e5f57 332 case BLE_STATUS_ERROR:
Vincent Coubard 259:323f588e5f57 333 default:
Vincent Coubard 259:323f588e5f57 334 // TODO remove characteristics and the service previously added.
Vincent Coubard 259:323f588e5f57 335 // remove service in the stack by using: Aci_Gatt_Del_Service
Vincent Coubard 259:323f588e5f57 336 // remove characteristics in the stack by using: Aci_Gatt_Del_Char
Vincent Coubard 259:323f588e5f57 337 // update service counter
Vincent Coubard 259:323f588e5f57 338 // destroy registered characteristic and updat echaracteristic counter
Vincent Coubard 259:323f588e5f57 339 return BLE_ERROR_INTERNAL_STACK_FAILURE;
Wolfgang Betz 130:770ce14d3d15 340 }
Wolfgang Betz 130:770ce14d3d15 341 }
Vincent Coubard 258:e5ef65120b06 342 }
Vincent Coubard 258:e5ef65120b06 343
Wolfgang Betz 130:770ce14d3d15 344 serviceCount++;
Vincent Coubard 258:e5ef65120b06 345
Vincent Coubard 258:e5ef65120b06 346 //FIXME: There is no GattService pointer array in GattServer.
Wolfgang Betz 130:770ce14d3d15 347 // There should be one? (Only the user is aware of GattServices!) Report to forum.
Vincent Coubard 258:e5ef65120b06 348
Wolfgang Betz 130:770ce14d3d15 349 return BLE_ERROR_NONE;
Wolfgang Betz 130:770ce14d3d15 350 }
Wolfgang Betz 130:770ce14d3d15 351
Wolfgang Betz 130:770ce14d3d15 352 /**************************************************************************/
Wolfgang Betz 130:770ce14d3d15 353 /*!
Andrea Palmieri 233:488e0e8b9b43 354 @brief Reads the value of a characteristic, based on char handle
Wolfgang Betz 130:770ce14d3d15 355
Andrea Palmieri 233:488e0e8b9b43 356 @param[in] attributeHandle
Wolfgang Betz 130:770ce14d3d15 357 The handle of the GattCharacteristic to read from
Wolfgang Betz 130:770ce14d3d15 358 @param[in] buffer
Wolfgang Betz 130:770ce14d3d15 359 Buffer to hold the the characteristic's value
Wolfgang Betz 130:770ce14d3d15 360 (raw byte array in LSB format)
Wolfgang Betz 130:770ce14d3d15 361 @param[in] lengthP
Wolfgang Betz 130:770ce14d3d15 362 The number of bytes read into the buffer
Wolfgang Betz 130:770ce14d3d15 363
Wolfgang Betz 130:770ce14d3d15 364 @returns ble_error_t
Wolfgang Betz 130:770ce14d3d15 365
Wolfgang Betz 130:770ce14d3d15 366 @retval BLE_ERROR_NONE
Wolfgang Betz 130:770ce14d3d15 367 Everything executed properly
Wolfgang Betz 130:770ce14d3d15 368
Wolfgang Betz 130:770ce14d3d15 369 @section EXAMPLE
Wolfgang Betz 130:770ce14d3d15 370
Wolfgang Betz 130:770ce14d3d15 371 @code
Wolfgang Betz 130:770ce14d3d15 372
Wolfgang Betz 130:770ce14d3d15 373 @endcode
Wolfgang Betz 130:770ce14d3d15 374 */
Wolfgang Betz 130:770ce14d3d15 375 /**************************************************************************/
Andrea Palmieri 229:9981f62cdb1a 376 ble_error_t BlueNRGGattServer::read(GattAttribute::Handle_t attributeHandle, uint8_t buffer[], uint16_t *lengthP)
Wolfgang Betz 130:770ce14d3d15 377 {
Andrea Palmieri 204:6a6d2f041905 378 tBleStatus ret;
Vincent Coubard 258:e5ef65120b06 379 uint16_t charHandle = attributeHandle;
Andrea Palmieri 204:6a6d2f041905 380
Andrea Palmieri 229:9981f62cdb1a 381 ret = aci_gatt_read_handle_value(charHandle, *lengthP, lengthP, buffer);
Andrea Palmieri 142:adf1567d3900 382
Andrea Palmieri 204:6a6d2f041905 383 if(ret == BLE_STATUS_SUCCESS) {
Andrea Palmieri 204:6a6d2f041905 384 return BLE_ERROR_NONE;
Andrea Palmieri 204:6a6d2f041905 385 }
Andrea Palmieri 204:6a6d2f041905 386 switch (ret) {
Andrea Palmieri 204:6a6d2f041905 387 case ERR_INVALID_HCI_CMD_PARAMS:
Andrea Palmieri 204:6a6d2f041905 388 return BLE_ERROR_INVALID_PARAM;
Andrea Palmieri 204:6a6d2f041905 389 default:
Andrea Palmieri 204:6a6d2f041905 390 return BLE_ERROR_UNSPECIFIED;
Andrea Palmieri 204:6a6d2f041905 391 }
Wolfgang Betz 130:770ce14d3d15 392 }
Wolfgang Betz 130:770ce14d3d15 393
Wolfgang Betz 130:770ce14d3d15 394 /**************************************************************************/
Wolfgang Betz 130:770ce14d3d15 395 /*!
Andrea Palmieri 233:488e0e8b9b43 396 @brief Reads the value of a characteristic, based on the connection
Andrea Palmieri 233:488e0e8b9b43 397 and char handle
Wolfgang Betz 130:770ce14d3d15 398
Andrea Palmieri 233:488e0e8b9b43 399 @param[in] connectionHandle
Andrea Palmieri 233:488e0e8b9b43 400 The handle of the connection
Andrea Palmieri 233:488e0e8b9b43 401 @param[in] attributeHandle
Wolfgang Betz 130:770ce14d3d15 402 The handle of the GattCharacteristic to write to
Wolfgang Betz 130:770ce14d3d15 403 @param[in] buffer
Wolfgang Betz 130:770ce14d3d15 404 Data to use when updating the characteristic's value
Wolfgang Betz 130:770ce14d3d15 405 (raw byte array in LSB format)
Andrea Palmieri 233:488e0e8b9b43 406 @param[in] lengthP
Wolfgang Betz 130:770ce14d3d15 407 The number of bytes in buffer
Wolfgang Betz 130:770ce14d3d15 408
Wolfgang Betz 130:770ce14d3d15 409 @returns ble_error_t
Wolfgang Betz 130:770ce14d3d15 410
Wolfgang Betz 130:770ce14d3d15 411 @retval BLE_ERROR_NONE
Wolfgang Betz 130:770ce14d3d15 412 Everything executed properly
Wolfgang Betz 130:770ce14d3d15 413
Wolfgang Betz 130:770ce14d3d15 414 @section EXAMPLE
Wolfgang Betz 130:770ce14d3d15 415
Wolfgang Betz 130:770ce14d3d15 416 @code
Wolfgang Betz 130:770ce14d3d15 417
Wolfgang Betz 130:770ce14d3d15 418 @endcode
Wolfgang Betz 130:770ce14d3d15 419 */
Wolfgang Betz 130:770ce14d3d15 420 /**************************************************************************/
Andrea Palmieri 229:9981f62cdb1a 421 ble_error_t BlueNRGGattServer::read(Gap::Handle_t connectionHandle,
Andrea Palmieri 229:9981f62cdb1a 422 GattAttribute::Handle_t attributeHandle,
Andrea Palmieri 229:9981f62cdb1a 423 uint8_t buffer[],
Andrea Palmieri 229:9981f62cdb1a 424 uint16_t *lengthP) {
Andrea Palmieri 142:adf1567d3900 425
Andrea Palmieri 142:adf1567d3900 426 /* avoid compiler warnings about unused variables */
Andrea Palmieri 142:adf1567d3900 427 (void)connectionHandle;
Andrea Palmieri 142:adf1567d3900 428 (void)attributeHandle;
Andrea Palmieri 142:adf1567d3900 429 (void)buffer;
Andrea Palmieri 142:adf1567d3900 430 (void)lengthP;
Andrea Palmieri 142:adf1567d3900 431
Andrea Palmieri 142:adf1567d3900 432 return BLE_ERROR_NONE;
Wolfgang Betz 130:770ce14d3d15 433 }
Wolfgang Betz 130:770ce14d3d15 434
Andrea Palmieri 229:9981f62cdb1a 435 ble_error_t BlueNRGGattServer::write(Gap::Handle_t connectionHandle,
Andrea Palmieri 229:9981f62cdb1a 436 GattAttribute::Handle_t,
Andrea Palmieri 229:9981f62cdb1a 437 const uint8_t[],
Andrea Palmieri 229:9981f62cdb1a 438 uint16_t, bool localOnly) {
Andrea Palmieri 142:adf1567d3900 439 /* avoid compiler warnings about unused variables */
Andrea Palmieri 142:adf1567d3900 440 (void)connectionHandle;
Andrea Palmieri 142:adf1567d3900 441 (void)localOnly;
Andrea Palmieri 142:adf1567d3900 442
Andrea Palmieri 142:adf1567d3900 443 return BLE_ERROR_NONE;
Wolfgang Betz 130:770ce14d3d15 444 }
Vincent Coubard 258:e5ef65120b06 445
Andrea Palmieri 229:9981f62cdb1a 446 ble_error_t BlueNRGGattServer::write(GattAttribute::Handle_t attributeHandle, const uint8_t buffer[], uint16_t len, bool localOnly)
Wolfgang Betz 130:770ce14d3d15 447 {
Andrea Palmieri 142:adf1567d3900 448 /* avoid compiler warnings about unused variables */
Andrea Palmieri 142:adf1567d3900 449 (void)localOnly;
Andrea Palmieri 142:adf1567d3900 450
Vincent Coubard 258:e5ef65120b06 451 // check that the len of the data to write are compatible with the characteristic
Vincent Coubard 258:e5ef65120b06 452 GattCharacteristic* characteristic = getCharacteristicFromHandle(attributeHandle);
Vincent Coubard 258:e5ef65120b06 453 if (!characteristic) {
Vincent Coubard 261:16cdf278f70a 454 PRINTF("characteristic not found\r\n");
Vincent Coubard 258:e5ef65120b06 455 return BLE_ERROR_INVALID_PARAM;
Vincent Coubard 258:e5ef65120b06 456 }
Vincent Coubard 258:e5ef65120b06 457
Vincent Coubard 258:e5ef65120b06 458 // assert the len in input is correct for this characteristic
Vincent Coubard 258:e5ef65120b06 459 const GattAttribute& value_attribute = characteristic->getValueAttribute();
Vincent Coubard 258:e5ef65120b06 460
Vincent Coubard 258:e5ef65120b06 461 // reject write if the lenght exceed the maximum lenght of this attribute
Vincent Coubard 258:e5ef65120b06 462 if (value_attribute.getMaxLength() < len) {
Vincent Coubard 261:16cdf278f70a 463 PRINTF("invalid variable length: %u, max length is: %u\r\n", len, value_attribute.getMaxLength());
Vincent Coubard 258:e5ef65120b06 464 return BLE_ERROR_INVALID_PARAM;
Vincent Coubard 258:e5ef65120b06 465 }
Vincent Coubard 258:e5ef65120b06 466
Vincent Coubard 258:e5ef65120b06 467 // reject write if the attribute size is fixed and the lenght in input is different than the
Vincent Coubard 258:e5ef65120b06 468 // length of the attribute.
Vincent Coubard 260:e93cbde933ce 469 if (value_attribute.hasVariableLength() == false && value_attribute.getMaxLength() != len) {
Vincent Coubard 261:16cdf278f70a 470 PRINTF("invalid fixed length: %u, len should be %u\r\n", len, value_attribute.getMaxLength());
Vincent Coubard 258:e5ef65120b06 471 return BLE_ERROR_INVALID_PARAM;
Vincent Coubard 258:e5ef65120b06 472 }
Vincent Coubard 258:e5ef65120b06 473
Andrea Palmieri 142:adf1567d3900 474 tBleStatus ret;
Andrea Palmieri 229:9981f62cdb1a 475
Andrea Palmieri 229:9981f62cdb1a 476 uint16_t charHandle = attributeHandle-BlueNRGGattServer::CHAR_VALUE_HANDLE;
Wolfgang Betz 130:770ce14d3d15 477
Andrea Palmieri 229:9981f62cdb1a 478 PRINTF("updating bleCharacteristic valueHandle=%u,\
Andrea Palmieri 229:9981f62cdb1a 479 corresponding serviceHandle=%u len=%d\n\r",
Andrea Palmieri 229:9981f62cdb1a 480 attributeHandle, bleCharHandleMap.find(charHandle)->second, len);
Andrea Palmieri 229:9981f62cdb1a 481
Andrea Palmieri 233:488e0e8b9b43 482 /*
Andrea Palmieri 233:488e0e8b9b43 483 * If notifications (or indications) are enabled on that characteristic, a notification (or indication)
Andrea Palmieri 233:488e0e8b9b43 484 * will be sent to the client after sending this command to the BlueNRG.
Andrea Palmieri 233:488e0e8b9b43 485 */
Andrea Palmieri 229:9981f62cdb1a 486 ret = aci_gatt_update_char_value(bleCharHandleMap.find(charHandle)->second, charHandle, 0, len, buffer);
Wolfgang Betz 130:770ce14d3d15 487
Wolfgang Betz 130:770ce14d3d15 488 if (ret != BLE_STATUS_SUCCESS){
Andrea Palmieri 207:b9df918d6d5a 489 PRINTF("Error while updating characteristic (ret=0x%x).\n\r", ret);
Andrea Palmieri 207:b9df918d6d5a 490 switch (ret) {
Andrea Palmieri 207:b9df918d6d5a 491 case BLE_STATUS_INVALID_HANDLE:
Andrea Palmieri 207:b9df918d6d5a 492 case BLE_STATUS_INVALID_PARAMETER:
Andrea Palmieri 207:b9df918d6d5a 493 return BLE_ERROR_INVALID_PARAM;
Andrea Palmieri 207:b9df918d6d5a 494 default:
Andrea Palmieri 207:b9df918d6d5a 495 return BLE_STACK_BUSY;
Andrea Palmieri 207:b9df918d6d5a 496 }
Wolfgang Betz 130:770ce14d3d15 497 }
Wolfgang Betz 130:770ce14d3d15 498
Wolfgang Betz 130:770ce14d3d15 499 return BLE_ERROR_NONE;
Wolfgang Betz 130:770ce14d3d15 500 }
Wolfgang Betz 130:770ce14d3d15 501
Wolfgang Betz 130:770ce14d3d15 502 /**************************************************************************/
Wolfgang Betz 130:770ce14d3d15 503 /*!
Wolfgang Betz 130:770ce14d3d15 504 @brief Reads a value according to the handle provided
Wolfgang Betz 130:770ce14d3d15 505
Andrea Palmieri 229:9981f62cdb1a 506 @param[in] attributeHandle
Andrea Palmieri 229:9981f62cdb1a 507 The handle of the attribute to read from
Wolfgang Betz 130:770ce14d3d15 508
Wolfgang Betz 130:770ce14d3d15 509 @returns ble_error_t
Wolfgang Betz 130:770ce14d3d15 510
Wolfgang Betz 130:770ce14d3d15 511 @retval BLE_ERROR_NONE
Wolfgang Betz 130:770ce14d3d15 512 Everything executed properly
Wolfgang Betz 130:770ce14d3d15 513
Wolfgang Betz 130:770ce14d3d15 514 @section EXAMPLE
Wolfgang Betz 130:770ce14d3d15 515
Wolfgang Betz 130:770ce14d3d15 516 @code
Wolfgang Betz 130:770ce14d3d15 517
Wolfgang Betz 130:770ce14d3d15 518 @endcode
Wolfgang Betz 130:770ce14d3d15 519 */
Wolfgang Betz 130:770ce14d3d15 520 /**************************************************************************/
Andrea Palmieri 229:9981f62cdb1a 521 ble_error_t BlueNRGGattServer::Read_Request_CB(uint16_t attributeHandle)
Wolfgang Betz 130:770ce14d3d15 522 {
Wolfgang Betz 130:770ce14d3d15 523 uint16_t gapConnectionHandle = BlueNRGGap::getInstance().getConnectionHandle();
Vincent Coubard 258:e5ef65120b06 524
Wolfgang Betz 130:770ce14d3d15 525 GattReadCallbackParams readParams;
Andrea Palmieri 229:9981f62cdb1a 526 readParams.handle = attributeHandle;
Wolfgang Betz 130:770ce14d3d15 527
Andrea Palmieri 229:9981f62cdb1a 528 //PRINTF("readParams.handle = %d\n\r", readParams.handle);
Wolfgang Betz 130:770ce14d3d15 529 HCIDataReadEvent(&readParams);
Vincent Coubard 258:e5ef65120b06 530
Wolfgang Betz 130:770ce14d3d15 531 //EXIT:
Wolfgang Betz 130:770ce14d3d15 532 if(gapConnectionHandle != 0){
Wolfgang Betz 132:51056160fa4a 533 //PRINTF("Calling aci_gatt_allow_read\n\r");
Wolfgang Betz 130:770ce14d3d15 534 aci_gatt_allow_read(gapConnectionHandle);
Wolfgang Betz 130:770ce14d3d15 535 }
Vincent Coubard 258:e5ef65120b06 536
Wolfgang Betz 130:770ce14d3d15 537 return BLE_ERROR_NONE;
Wolfgang Betz 130:770ce14d3d15 538 }
Wolfgang Betz 130:770ce14d3d15 539
Wolfgang Betz 130:770ce14d3d15 540 /**************************************************************************/
Wolfgang Betz 130:770ce14d3d15 541 /*!
Wolfgang Betz 130:770ce14d3d15 542 @brief Returns the GattCharacteristic according to the handle provided
Wolfgang Betz 130:770ce14d3d15 543
Andrea Palmieri 229:9981f62cdb1a 544 @param[in] attrHandle
Andrea Palmieri 229:9981f62cdb1a 545 The handle of the attribute
Wolfgang Betz 130:770ce14d3d15 546
Wolfgang Betz 130:770ce14d3d15 547 @returns ble_error_t
Wolfgang Betz 130:770ce14d3d15 548
Wolfgang Betz 130:770ce14d3d15 549 @retval BLE_ERROR_NONE
Wolfgang Betz 130:770ce14d3d15 550 Everything executed properly
Wolfgang Betz 130:770ce14d3d15 551
Wolfgang Betz 130:770ce14d3d15 552 @section EXAMPLE
Wolfgang Betz 130:770ce14d3d15 553
Wolfgang Betz 130:770ce14d3d15 554 @code
Wolfgang Betz 130:770ce14d3d15 555
Wolfgang Betz 130:770ce14d3d15 556 @endcode
Wolfgang Betz 130:770ce14d3d15 557 */
Wolfgang Betz 130:770ce14d3d15 558 /**************************************************************************/
Wolfgang Betz 130:770ce14d3d15 559 GattCharacteristic* BlueNRGGattServer::getCharacteristicFromHandle(uint16_t attrHandle)
Wolfgang Betz 130:770ce14d3d15 560 {
Wolfgang Betz 130:770ce14d3d15 561 GattCharacteristic *p_char = NULL;
Wolfgang Betz 130:770ce14d3d15 562 int i;
Wolfgang Betz 130:770ce14d3d15 563 uint16_t handle, handle_1;
Wolfgang Betz 130:770ce14d3d15 564
Andrea Palmieri 229:9981f62cdb1a 565 PRINTF("BlueNRGGattServer::getCharacteristicFromHandle()>>Attr Handle received %d\n\r",attrHandle);
Wolfgang Betz 130:770ce14d3d15 566 for(i=0; i<characteristicCount; i++)
Wolfgang Betz 130:770ce14d3d15 567 {
Andrea Palmieri 229:9981f62cdb1a 568 handle = p_characteristics[i]->getValueAttribute().getHandle()-BlueNRGGattServer::CHAR_VALUE_HANDLE;
Wolfgang Betz 132:51056160fa4a 569 PRINTF("handle(%d)=%d\n\r", i, handle);
Wolfgang Betz 130:770ce14d3d15 570 if(i==characteristicCount-1)//Last Characteristic check
Wolfgang Betz 130:770ce14d3d15 571 {
Wolfgang Betz 130:770ce14d3d15 572 if(attrHandle>=handle)
Wolfgang Betz 130:770ce14d3d15 573 {
Wolfgang Betz 130:770ce14d3d15 574 p_char = p_characteristics[i];
Wolfgang Betz 132:51056160fa4a 575 PRINTF("Found Characteristic Properties 0x%x (handle=%d)\n\r",p_char->getProperties(), handle);
Wolfgang Betz 130:770ce14d3d15 576 break;
Vincent Coubard 258:e5ef65120b06 577 }
Wolfgang Betz 130:770ce14d3d15 578 }
Wolfgang Betz 130:770ce14d3d15 579 else {
Andrea Palmieri 229:9981f62cdb1a 580 handle_1 = p_characteristics[i+1]->getValueAttribute().getHandle()-BlueNRGGattServer::CHAR_VALUE_HANDLE;
Wolfgang Betz 130:770ce14d3d15 581 //Testing if attribute handle is between two Characteristic Handles
Wolfgang Betz 130:770ce14d3d15 582 if(attrHandle>=handle && attrHandle<handle_1)
Wolfgang Betz 130:770ce14d3d15 583 {
Wolfgang Betz 130:770ce14d3d15 584 p_char = p_characteristics[i];
Wolfgang Betz 132:51056160fa4a 585 PRINTF("Found Characteristic Properties 0x%x (handle=%d handle_1=%d)\n\r",p_char->getProperties(), handle, handle_1);
Wolfgang Betz 130:770ce14d3d15 586 break;
Wolfgang Betz 130:770ce14d3d15 587 } else continue;
Wolfgang Betz 130:770ce14d3d15 588 }
Wolfgang Betz 130:770ce14d3d15 589 }
Wolfgang Betz 130:770ce14d3d15 590
Wolfgang Betz 130:770ce14d3d15 591 return p_char;
Wolfgang Betz 130:770ce14d3d15 592 }
Wolfgang Betz 130:770ce14d3d15 593
Wolfgang Betz 130:770ce14d3d15 594 void BlueNRGGattServer::HCIDataWrittenEvent(const GattWriteCallbackParams *params) {
Wolfgang Betz 130:770ce14d3d15 595 this->handleDataWrittenEvent(params);
Wolfgang Betz 130:770ce14d3d15 596 }
Vincent Coubard 258:e5ef65120b06 597
Wolfgang Betz 130:770ce14d3d15 598 void BlueNRGGattServer::HCIDataReadEvent(const GattReadCallbackParams *params) {
Wolfgang Betz 132:51056160fa4a 599 PRINTF("Called HCIDataReadEvent\n\r");
Wolfgang Betz 130:770ce14d3d15 600 this->handleDataReadEvent(params);
Wolfgang Betz 130:770ce14d3d15 601 }
Wolfgang Betz 130:770ce14d3d15 602
Wolfgang Betz 130:770ce14d3d15 603 void BlueNRGGattServer::HCIEvent(GattServerEvents::gattEvent_e type, uint16_t charHandle) {
Wolfgang Betz 130:770ce14d3d15 604 this->handleEvent(type, charHandle);
Wolfgang Betz 130:770ce14d3d15 605 }
Wolfgang Betz 130:770ce14d3d15 606
Wolfgang Betz 130:770ce14d3d15 607 void BlueNRGGattServer::HCIDataSentEvent(unsigned count) {
Wolfgang Betz 130:770ce14d3d15 608 this->handleDataSentEvent(count);
Wolfgang Betz 130:770ce14d3d15 609 }
Wolfgang Betz 130:770ce14d3d15 610
Vincent Coubard 258:e5ef65120b06 611
Wolfgang Betz 130:770ce14d3d15 612 ble_error_t BlueNRGGattServer::initializeGATTDatabase(void) {
Vincent Coubard 258:e5ef65120b06 613 // <TODO>
Vincent Coubard 258:e5ef65120b06 614 return (ble_error_t)0;
Wolfgang Betz 130:770ce14d3d15 615 }
Andrea Palmieri 229:9981f62cdb1a 616
Andrea Palmieri 229:9981f62cdb1a 617 /**************************************************************************/
Andrea Palmieri 229:9981f62cdb1a 618 /*!
Andrea Palmieri 229:9981f62cdb1a 619 @brief Clear BlueNRGGattServer's state.
Andrea Palmieri 229:9981f62cdb1a 620
Andrea Palmieri 229:9981f62cdb1a 621 @returns ble_error_t
Andrea Palmieri 229:9981f62cdb1a 622
Andrea Palmieri 229:9981f62cdb1a 623 @retval BLE_ERROR_NONE
Andrea Palmieri 229:9981f62cdb1a 624 Everything executed properly
Andrea Palmieri 229:9981f62cdb1a 625 */
Andrea Palmieri 229:9981f62cdb1a 626 /**************************************************************************/
Andrea Palmieri 229:9981f62cdb1a 627 ble_error_t BlueNRGGattServer::reset(void)
Andrea Palmieri 229:9981f62cdb1a 628 {
Andrea Palmieri 229:9981f62cdb1a 629 /* Clear all state that is from the parent, including private members */
Andrea Palmieri 229:9981f62cdb1a 630 if (GattServer::reset() != BLE_ERROR_NONE) {
Andrea Palmieri 229:9981f62cdb1a 631 return BLE_ERROR_INVALID_STATE;
Andrea Palmieri 229:9981f62cdb1a 632 }
Andrea Palmieri 229:9981f62cdb1a 633
Andrea Palmieri 229:9981f62cdb1a 634 /* Clear class members */
Andrea Palmieri 229:9981f62cdb1a 635 memset(p_characteristics, 0, sizeof(p_characteristics));
Andrea Palmieri 229:9981f62cdb1a 636 memset(bleCharacteristicHandles, 0, sizeof(bleCharacteristicHandles));
Andrea Palmieri 229:9981f62cdb1a 637 serviceCount = 0;
Andrea Palmieri 229:9981f62cdb1a 638 characteristicCount = 0;
Andrea Palmieri 229:9981f62cdb1a 639
Andrea Palmieri 229:9981f62cdb1a 640 return BLE_ERROR_NONE;
Vincent Coubard 259:323f588e5f57 641 }
Vincent Coubard 259:323f588e5f57 642
Vincent Coubard 259:323f588e5f57 643
Vincent Coubard 259:323f588e5f57 644 /// compute the number of attributes needed by this service.
Vincent Coubard 259:323f588e5f57 645 uint16_t BlueNRGGattServer::computeAttributesRecord(GattService& service) {
Vincent Coubard 259:323f588e5f57 646 uint16_t attribute_records = 1;
Vincent Coubard 259:323f588e5f57 647
Vincent Coubard 259:323f588e5f57 648 for (uint8_t characteristic_index = 0; characteristic_index < service.getCharacteristicCount(); ++characteristic_index) {
Vincent Coubard 259:323f588e5f57 649 // add two attributes, one for the characteristic declaration
Vincent Coubard 259:323f588e5f57 650 // and the other for the characteristic value.
Vincent Coubard 259:323f588e5f57 651 attribute_records += 2;
Vincent Coubard 259:323f588e5f57 652
Vincent Coubard 259:323f588e5f57 653 const GattCharacteristic* characteristic = service.getCharacteristic(characteristic_index);
Vincent Coubard 259:323f588e5f57 654 const uint8_t properties = characteristic->getProperties();
Vincent Coubard 259:323f588e5f57 655 // if notify or indicate are present, two attributes are
Vincent Coubard 259:323f588e5f57 656 // needed
Vincent Coubard 259:323f588e5f57 657 if ((properties & GattCharacteristic::BLE_GATT_CHAR_PROPERTIES_NOTIFY) ||
Vincent Coubard 259:323f588e5f57 658 (properties & GattCharacteristic::BLE_GATT_CHAR_PROPERTIES_INDICATE)) {
Vincent Coubard 259:323f588e5f57 659 attribute_records += 2;
Vincent Coubard 259:323f588e5f57 660 }
Vincent Coubard 259:323f588e5f57 661
Vincent Coubard 259:323f588e5f57 662 // if broadcast is set, two attributes are needed
Vincent Coubard 259:323f588e5f57 663 if (properties & GattCharacteristic::BLE_GATT_CHAR_PROPERTIES_BROADCAST) {
Vincent Coubard 259:323f588e5f57 664 attribute_records += 2;
Vincent Coubard 259:323f588e5f57 665 }
Vincent Coubard 259:323f588e5f57 666
Vincent Coubard 259:323f588e5f57 667 // if extended properties flag is set, two attributes are needed
Vincent Coubard 259:323f588e5f57 668 if (properties & GattCharacteristic::BLE_GATT_CHAR_PROPERTIES_EXTENDED_PROPERTIES) {
Vincent Coubard 259:323f588e5f57 669 attribute_records += 2;
Vincent Coubard 259:323f588e5f57 670 }
Vincent Coubard 259:323f588e5f57 671
Vincent Coubard 259:323f588e5f57 672 attribute_records += characteristic->getDescriptorCount();
Vincent Coubard 259:323f588e5f57 673 }
Vincent Coubard 259:323f588e5f57 674
Vincent Coubard 259:323f588e5f57 675 // for some reason, if there is just a service, this value should
Vincent Coubard 259:323f588e5f57 676 // be equal to 5
Vincent Coubard 259:323f588e5f57 677 if (attribute_records == 1) {
Vincent Coubard 259:323f588e5f57 678 attribute_records = 5;
Vincent Coubard 259:323f588e5f57 679 }
Vincent Coubard 259:323f588e5f57 680
Vincent Coubard 259:323f588e5f57 681 return attribute_records;
Vincent Coubard 258:e5ef65120b06 682 }