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:25 2016 +0100
Branch:
f75800800e6bd3fe65cb03783b4ceec360909c66
Revision:
263:8516afb5e29c
Parent:
262:a3460768f3b7
Child:
267:cd7870e466b3
Sync with f75800800e6bd3fe65cb03783b4ceec360909c66

2016-07-11 09:58:16+01:00: Vincent Coubard
Handle write to descriptors.

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 263:8516afb5e29c 458 // if the attribute handle is the attribute handle of the characteristic value then
Vincent Coubard 263:8516afb5e29c 459 // write the value
Vincent Coubard 263:8516afb5e29c 460 if (attributeHandle == characteristic->getValueHandle()) {
Vincent Coubard 263:8516afb5e29c 461 // assert the len in input is correct for this characteristic
Vincent Coubard 263:8516afb5e29c 462 const GattAttribute& value_attribute = characteristic->getValueAttribute();
Vincent Coubard 258:e5ef65120b06 463
Vincent Coubard 263:8516afb5e29c 464 // reject write if the lenght exceed the maximum lenght of this attribute
Vincent Coubard 263:8516afb5e29c 465 if (value_attribute.getMaxLength() < len) {
Vincent Coubard 263:8516afb5e29c 466 PRINTF("invalid variable length: %u, max length is: %u\r\n", len, value_attribute.getMaxLength());
Vincent Coubard 263:8516afb5e29c 467 return BLE_ERROR_INVALID_PARAM;
Vincent Coubard 263:8516afb5e29c 468 }
Vincent Coubard 258:e5ef65120b06 469
Vincent Coubard 263:8516afb5e29c 470 // reject write if the attribute size is fixed and the lenght in input is different than the
Vincent Coubard 263:8516afb5e29c 471 // length of the attribute.
Vincent Coubard 263:8516afb5e29c 472 if (value_attribute.hasVariableLength() == false && value_attribute.getMaxLength() != len) {
Vincent Coubard 263:8516afb5e29c 473 PRINTF("invalid fixed length: %u, len should be %u\r\n", len, value_attribute.getMaxLength());
Vincent Coubard 263:8516afb5e29c 474 return BLE_ERROR_INVALID_PARAM;
Vincent Coubard 263:8516afb5e29c 475 }
Vincent Coubard 263:8516afb5e29c 476
Vincent Coubard 263:8516afb5e29c 477 tBleStatus ret;
Vincent Coubard 258:e5ef65120b06 478
Vincent Coubard 263:8516afb5e29c 479 uint16_t charHandle = characteristic->getValueHandle() - BlueNRGGattServer::CHAR_VALUE_HANDLE;
Vincent Coubard 263:8516afb5e29c 480
Vincent Coubard 263:8516afb5e29c 481 PRINTF("updating bleCharacteristic valueHandle=%u,\
Vincent Coubard 263:8516afb5e29c 482 corresponding serviceHandle=%u len=%d\n\r",
Vincent Coubard 263:8516afb5e29c 483 attributeHandle, bleCharHandleMap.find(charHandle)->second, len);
Andrea Palmieri 229:9981f62cdb1a 484
Vincent Coubard 263:8516afb5e29c 485 /*
Vincent Coubard 263:8516afb5e29c 486 * If notifications (or indications) are enabled on that characteristic, a notification (or indication)
Vincent Coubard 263:8516afb5e29c 487 * will be sent to the client after sending this command to the BlueNRG.
Vincent Coubard 263:8516afb5e29c 488 */
Vincent Coubard 263:8516afb5e29c 489 ret = aci_gatt_update_char_value(bleCharHandleMap.find(charHandle)->second, charHandle, 0, len, buffer);
Wolfgang Betz 130:770ce14d3d15 490
Vincent Coubard 263:8516afb5e29c 491 if (ret != BLE_STATUS_SUCCESS){
Vincent Coubard 263:8516afb5e29c 492 PRINTF("Error while updating characteristic (ret=0x%x).\n\r", ret);
Vincent Coubard 263:8516afb5e29c 493 switch (ret) {
Vincent Coubard 263:8516afb5e29c 494 case BLE_STATUS_INVALID_HANDLE:
Vincent Coubard 263:8516afb5e29c 495 case BLE_STATUS_INVALID_PARAMETER:
Vincent Coubard 263:8516afb5e29c 496 return BLE_ERROR_INVALID_PARAM;
Vincent Coubard 263:8516afb5e29c 497 default:
Vincent Coubard 263:8516afb5e29c 498 return BLE_STACK_BUSY;
Vincent Coubard 263:8516afb5e29c 499 }
Vincent Coubard 263:8516afb5e29c 500 }
Andrea Palmieri 229:9981f62cdb1a 501
Vincent Coubard 263:8516afb5e29c 502 return BLE_ERROR_NONE;
Vincent Coubard 263:8516afb5e29c 503 } else {
Vincent Coubard 263:8516afb5e29c 504 // write this handle has a descriptor handle
Vincent Coubard 263:8516afb5e29c 505 uint16_t charHandle = characteristic->getValueHandle() - BlueNRGGattServer::CHAR_VALUE_HANDLE;
Vincent Coubard 263:8516afb5e29c 506 uint16_t service_handle = bleCharHandleMap.find(charHandle)->second;
Wolfgang Betz 130:770ce14d3d15 507
Vincent Coubard 263:8516afb5e29c 508 tBleStatus ret = aci_gatt_set_desc_value(
Vincent Coubard 263:8516afb5e29c 509 service_handle,
Vincent Coubard 263:8516afb5e29c 510 charHandle,
Vincent Coubard 263:8516afb5e29c 511 attributeHandle,
Vincent Coubard 263:8516afb5e29c 512 0,
Vincent Coubard 263:8516afb5e29c 513 len,
Vincent Coubard 263:8516afb5e29c 514 buffer
Vincent Coubard 263:8516afb5e29c 515 );
Vincent Coubard 263:8516afb5e29c 516
Vincent Coubard 263:8516afb5e29c 517 if (ret != BLE_STATUS_SUCCESS){
Vincent Coubard 263:8516afb5e29c 518 PRINTF("Error while updating characteristic descriptor (ret=0x%x).\n\r", ret);
Vincent Coubard 263:8516afb5e29c 519 switch (ret) {
Vincent Coubard 263:8516afb5e29c 520 case BLE_STATUS_INVALID_HANDLE:
Vincent Coubard 263:8516afb5e29c 521 case BLE_STATUS_INVALID_PARAMETER:
Vincent Coubard 263:8516afb5e29c 522 return BLE_ERROR_INVALID_PARAM;
Vincent Coubard 263:8516afb5e29c 523 default:
Vincent Coubard 263:8516afb5e29c 524 return BLE_STACK_BUSY;
Vincent Coubard 263:8516afb5e29c 525 }
Vincent Coubard 263:8516afb5e29c 526 }
Vincent Coubard 263:8516afb5e29c 527
Vincent Coubard 263:8516afb5e29c 528 return BLE_ERROR_NONE;
Wolfgang Betz 130:770ce14d3d15 529 }
Wolfgang Betz 130:770ce14d3d15 530 }
Wolfgang Betz 130:770ce14d3d15 531
Wolfgang Betz 130:770ce14d3d15 532 /**************************************************************************/
Wolfgang Betz 130:770ce14d3d15 533 /*!
Wolfgang Betz 130:770ce14d3d15 534 @brief Reads a value according to the handle provided
Wolfgang Betz 130:770ce14d3d15 535
Andrea Palmieri 229:9981f62cdb1a 536 @param[in] attributeHandle
Andrea Palmieri 229:9981f62cdb1a 537 The handle of the attribute to read from
Wolfgang Betz 130:770ce14d3d15 538
Wolfgang Betz 130:770ce14d3d15 539 @returns ble_error_t
Wolfgang Betz 130:770ce14d3d15 540
Wolfgang Betz 130:770ce14d3d15 541 @retval BLE_ERROR_NONE
Wolfgang Betz 130:770ce14d3d15 542 Everything executed properly
Wolfgang Betz 130:770ce14d3d15 543
Wolfgang Betz 130:770ce14d3d15 544 @section EXAMPLE
Wolfgang Betz 130:770ce14d3d15 545
Wolfgang Betz 130:770ce14d3d15 546 @code
Wolfgang Betz 130:770ce14d3d15 547
Wolfgang Betz 130:770ce14d3d15 548 @endcode
Wolfgang Betz 130:770ce14d3d15 549 */
Wolfgang Betz 130:770ce14d3d15 550 /**************************************************************************/
Andrea Palmieri 229:9981f62cdb1a 551 ble_error_t BlueNRGGattServer::Read_Request_CB(uint16_t attributeHandle)
Wolfgang Betz 130:770ce14d3d15 552 {
Wolfgang Betz 130:770ce14d3d15 553 uint16_t gapConnectionHandle = BlueNRGGap::getInstance().getConnectionHandle();
Vincent Coubard 258:e5ef65120b06 554
Wolfgang Betz 130:770ce14d3d15 555 GattReadCallbackParams readParams;
Andrea Palmieri 229:9981f62cdb1a 556 readParams.handle = attributeHandle;
Wolfgang Betz 130:770ce14d3d15 557
Andrea Palmieri 229:9981f62cdb1a 558 //PRINTF("readParams.handle = %d\n\r", readParams.handle);
Wolfgang Betz 130:770ce14d3d15 559 HCIDataReadEvent(&readParams);
Vincent Coubard 258:e5ef65120b06 560
Wolfgang Betz 130:770ce14d3d15 561 //EXIT:
Wolfgang Betz 130:770ce14d3d15 562 if(gapConnectionHandle != 0){
Wolfgang Betz 132:51056160fa4a 563 //PRINTF("Calling aci_gatt_allow_read\n\r");
Wolfgang Betz 130:770ce14d3d15 564 aci_gatt_allow_read(gapConnectionHandle);
Wolfgang Betz 130:770ce14d3d15 565 }
Vincent Coubard 258:e5ef65120b06 566
Wolfgang Betz 130:770ce14d3d15 567 return BLE_ERROR_NONE;
Wolfgang Betz 130:770ce14d3d15 568 }
Wolfgang Betz 130:770ce14d3d15 569
Wolfgang Betz 130:770ce14d3d15 570 /**************************************************************************/
Wolfgang Betz 130:770ce14d3d15 571 /*!
Wolfgang Betz 130:770ce14d3d15 572 @brief Returns the GattCharacteristic according to the handle provided
Wolfgang Betz 130:770ce14d3d15 573
Andrea Palmieri 229:9981f62cdb1a 574 @param[in] attrHandle
Andrea Palmieri 229:9981f62cdb1a 575 The handle of the attribute
Wolfgang Betz 130:770ce14d3d15 576
Wolfgang Betz 130:770ce14d3d15 577 @returns ble_error_t
Wolfgang Betz 130:770ce14d3d15 578
Wolfgang Betz 130:770ce14d3d15 579 @retval BLE_ERROR_NONE
Wolfgang Betz 130:770ce14d3d15 580 Everything executed properly
Wolfgang Betz 130:770ce14d3d15 581
Wolfgang Betz 130:770ce14d3d15 582 @section EXAMPLE
Wolfgang Betz 130:770ce14d3d15 583
Wolfgang Betz 130:770ce14d3d15 584 @code
Wolfgang Betz 130:770ce14d3d15 585
Wolfgang Betz 130:770ce14d3d15 586 @endcode
Wolfgang Betz 130:770ce14d3d15 587 */
Wolfgang Betz 130:770ce14d3d15 588 /**************************************************************************/
Wolfgang Betz 130:770ce14d3d15 589 GattCharacteristic* BlueNRGGattServer::getCharacteristicFromHandle(uint16_t attrHandle)
Wolfgang Betz 130:770ce14d3d15 590 {
Wolfgang Betz 130:770ce14d3d15 591 GattCharacteristic *p_char = NULL;
Wolfgang Betz 130:770ce14d3d15 592 int i;
Wolfgang Betz 130:770ce14d3d15 593 uint16_t handle, handle_1;
Wolfgang Betz 130:770ce14d3d15 594
Andrea Palmieri 229:9981f62cdb1a 595 PRINTF("BlueNRGGattServer::getCharacteristicFromHandle()>>Attr Handle received %d\n\r",attrHandle);
Wolfgang Betz 130:770ce14d3d15 596 for(i=0; i<characteristicCount; i++)
Wolfgang Betz 130:770ce14d3d15 597 {
Andrea Palmieri 229:9981f62cdb1a 598 handle = p_characteristics[i]->getValueAttribute().getHandle()-BlueNRGGattServer::CHAR_VALUE_HANDLE;
Wolfgang Betz 132:51056160fa4a 599 PRINTF("handle(%d)=%d\n\r", i, handle);
Wolfgang Betz 130:770ce14d3d15 600 if(i==characteristicCount-1)//Last Characteristic check
Wolfgang Betz 130:770ce14d3d15 601 {
Wolfgang Betz 130:770ce14d3d15 602 if(attrHandle>=handle)
Wolfgang Betz 130:770ce14d3d15 603 {
Wolfgang Betz 130:770ce14d3d15 604 p_char = p_characteristics[i];
Wolfgang Betz 132:51056160fa4a 605 PRINTF("Found Characteristic Properties 0x%x (handle=%d)\n\r",p_char->getProperties(), handle);
Wolfgang Betz 130:770ce14d3d15 606 break;
Vincent Coubard 258:e5ef65120b06 607 }
Wolfgang Betz 130:770ce14d3d15 608 }
Wolfgang Betz 130:770ce14d3d15 609 else {
Andrea Palmieri 229:9981f62cdb1a 610 handle_1 = p_characteristics[i+1]->getValueAttribute().getHandle()-BlueNRGGattServer::CHAR_VALUE_HANDLE;
Wolfgang Betz 130:770ce14d3d15 611 //Testing if attribute handle is between two Characteristic Handles
Wolfgang Betz 130:770ce14d3d15 612 if(attrHandle>=handle && attrHandle<handle_1)
Wolfgang Betz 130:770ce14d3d15 613 {
Wolfgang Betz 130:770ce14d3d15 614 p_char = p_characteristics[i];
Wolfgang Betz 132:51056160fa4a 615 PRINTF("Found Characteristic Properties 0x%x (handle=%d handle_1=%d)\n\r",p_char->getProperties(), handle, handle_1);
Wolfgang Betz 130:770ce14d3d15 616 break;
Wolfgang Betz 130:770ce14d3d15 617 } else continue;
Wolfgang Betz 130:770ce14d3d15 618 }
Wolfgang Betz 130:770ce14d3d15 619 }
Wolfgang Betz 130:770ce14d3d15 620
Wolfgang Betz 130:770ce14d3d15 621 return p_char;
Wolfgang Betz 130:770ce14d3d15 622 }
Wolfgang Betz 130:770ce14d3d15 623
Wolfgang Betz 130:770ce14d3d15 624 void BlueNRGGattServer::HCIDataWrittenEvent(const GattWriteCallbackParams *params) {
Wolfgang Betz 130:770ce14d3d15 625 this->handleDataWrittenEvent(params);
Wolfgang Betz 130:770ce14d3d15 626 }
Vincent Coubard 258:e5ef65120b06 627
Wolfgang Betz 130:770ce14d3d15 628 void BlueNRGGattServer::HCIDataReadEvent(const GattReadCallbackParams *params) {
Wolfgang Betz 132:51056160fa4a 629 PRINTF("Called HCIDataReadEvent\n\r");
Wolfgang Betz 130:770ce14d3d15 630 this->handleDataReadEvent(params);
Wolfgang Betz 130:770ce14d3d15 631 }
Wolfgang Betz 130:770ce14d3d15 632
Wolfgang Betz 130:770ce14d3d15 633 void BlueNRGGattServer::HCIEvent(GattServerEvents::gattEvent_e type, uint16_t charHandle) {
Wolfgang Betz 130:770ce14d3d15 634 this->handleEvent(type, charHandle);
Wolfgang Betz 130:770ce14d3d15 635 }
Wolfgang Betz 130:770ce14d3d15 636
Wolfgang Betz 130:770ce14d3d15 637 void BlueNRGGattServer::HCIDataSentEvent(unsigned count) {
Wolfgang Betz 130:770ce14d3d15 638 this->handleDataSentEvent(count);
Wolfgang Betz 130:770ce14d3d15 639 }
Wolfgang Betz 130:770ce14d3d15 640
Vincent Coubard 258:e5ef65120b06 641
Wolfgang Betz 130:770ce14d3d15 642 ble_error_t BlueNRGGattServer::initializeGATTDatabase(void) {
Vincent Coubard 258:e5ef65120b06 643 // <TODO>
Vincent Coubard 258:e5ef65120b06 644 return (ble_error_t)0;
Wolfgang Betz 130:770ce14d3d15 645 }
Andrea Palmieri 229:9981f62cdb1a 646
Andrea Palmieri 229:9981f62cdb1a 647 /**************************************************************************/
Andrea Palmieri 229:9981f62cdb1a 648 /*!
Andrea Palmieri 229:9981f62cdb1a 649 @brief Clear BlueNRGGattServer's state.
Andrea Palmieri 229:9981f62cdb1a 650
Andrea Palmieri 229:9981f62cdb1a 651 @returns ble_error_t
Andrea Palmieri 229:9981f62cdb1a 652
Andrea Palmieri 229:9981f62cdb1a 653 @retval BLE_ERROR_NONE
Andrea Palmieri 229:9981f62cdb1a 654 Everything executed properly
Andrea Palmieri 229:9981f62cdb1a 655 */
Andrea Palmieri 229:9981f62cdb1a 656 /**************************************************************************/
Andrea Palmieri 229:9981f62cdb1a 657 ble_error_t BlueNRGGattServer::reset(void)
Andrea Palmieri 229:9981f62cdb1a 658 {
Andrea Palmieri 229:9981f62cdb1a 659 /* Clear all state that is from the parent, including private members */
Andrea Palmieri 229:9981f62cdb1a 660 if (GattServer::reset() != BLE_ERROR_NONE) {
Andrea Palmieri 229:9981f62cdb1a 661 return BLE_ERROR_INVALID_STATE;
Andrea Palmieri 229:9981f62cdb1a 662 }
Andrea Palmieri 229:9981f62cdb1a 663
Andrea Palmieri 229:9981f62cdb1a 664 /* Clear class members */
Andrea Palmieri 229:9981f62cdb1a 665 memset(p_characteristics, 0, sizeof(p_characteristics));
Andrea Palmieri 229:9981f62cdb1a 666 memset(bleCharacteristicHandles, 0, sizeof(bleCharacteristicHandles));
Andrea Palmieri 229:9981f62cdb1a 667 serviceCount = 0;
Andrea Palmieri 229:9981f62cdb1a 668 characteristicCount = 0;
Andrea Palmieri 229:9981f62cdb1a 669
Andrea Palmieri 229:9981f62cdb1a 670 return BLE_ERROR_NONE;
Vincent Coubard 259:323f588e5f57 671 }
Vincent Coubard 259:323f588e5f57 672
Vincent Coubard 259:323f588e5f57 673
Vincent Coubard 259:323f588e5f57 674 /// compute the number of attributes needed by this service.
Vincent Coubard 259:323f588e5f57 675 uint16_t BlueNRGGattServer::computeAttributesRecord(GattService& service) {
Vincent Coubard 259:323f588e5f57 676 uint16_t attribute_records = 1;
Vincent Coubard 259:323f588e5f57 677
Vincent Coubard 259:323f588e5f57 678 for (uint8_t characteristic_index = 0; characteristic_index < service.getCharacteristicCount(); ++characteristic_index) {
Vincent Coubard 259:323f588e5f57 679 // add two attributes, one for the characteristic declaration
Vincent Coubard 259:323f588e5f57 680 // and the other for the characteristic value.
Vincent Coubard 259:323f588e5f57 681 attribute_records += 2;
Vincent Coubard 259:323f588e5f57 682
Vincent Coubard 259:323f588e5f57 683 const GattCharacteristic* characteristic = service.getCharacteristic(characteristic_index);
Vincent Coubard 259:323f588e5f57 684 const uint8_t properties = characteristic->getProperties();
Vincent Coubard 259:323f588e5f57 685 // if notify or indicate are present, two attributes are
Vincent Coubard 259:323f588e5f57 686 // needed
Vincent Coubard 259:323f588e5f57 687 if ((properties & GattCharacteristic::BLE_GATT_CHAR_PROPERTIES_NOTIFY) ||
Vincent Coubard 259:323f588e5f57 688 (properties & GattCharacteristic::BLE_GATT_CHAR_PROPERTIES_INDICATE)) {
Vincent Coubard 259:323f588e5f57 689 attribute_records += 2;
Vincent Coubard 259:323f588e5f57 690 }
Vincent Coubard 259:323f588e5f57 691
Vincent Coubard 259:323f588e5f57 692 // if broadcast is set, two attributes are needed
Vincent Coubard 259:323f588e5f57 693 if (properties & GattCharacteristic::BLE_GATT_CHAR_PROPERTIES_BROADCAST) {
Vincent Coubard 259:323f588e5f57 694 attribute_records += 2;
Vincent Coubard 259:323f588e5f57 695 }
Vincent Coubard 259:323f588e5f57 696
Vincent Coubard 259:323f588e5f57 697 // if extended properties flag is set, two attributes are needed
Vincent Coubard 259:323f588e5f57 698 if (properties & GattCharacteristic::BLE_GATT_CHAR_PROPERTIES_EXTENDED_PROPERTIES) {
Vincent Coubard 259:323f588e5f57 699 attribute_records += 2;
Vincent Coubard 259:323f588e5f57 700 }
Vincent Coubard 259:323f588e5f57 701
Vincent Coubard 259:323f588e5f57 702 attribute_records += characteristic->getDescriptorCount();
Vincent Coubard 259:323f588e5f57 703 }
Vincent Coubard 259:323f588e5f57 704
Vincent Coubard 259:323f588e5f57 705 // for some reason, if there is just a service, this value should
Vincent Coubard 259:323f588e5f57 706 // be equal to 5
Vincent Coubard 259:323f588e5f57 707 if (attribute_records == 1) {
Vincent Coubard 259:323f588e5f57 708 attribute_records = 5;
Vincent Coubard 259:323f588e5f57 709 }
Vincent Coubard 259:323f588e5f57 710
Vincent Coubard 259:323f588e5f57 711 return attribute_records;
Vincent Coubard 258:e5ef65120b06 712 }