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:
Andrea Palmieri
Date:
Fri Sep 16 12:03:25 2016 +0200
Revision:
307:fa98703ece8e
Parent:
293:5a1f577bf92f
Sync with 21bfd161ace255bb6214d6b74cae1fd30b3e24c9

2016-09-16 11:53:47+02:00: Andrea Palmieri
Get rid of warnings

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