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:31 2016 +0100
Branch:
72a03e94578ba288a289bed81955d4d04ab6702f
Revision:
269:cd037b36a62b
Parent:
267:cd7870e466b3
Child:
278:a5209d8cfd61
Sync with 72a03e94578ba288a289bed81955d4d04ab6702f

2016-07-13 15:00:32+02:00: Andrea Palmieri
Get rid of warnings

Signed-off-by: Andrea Palmieri <andrea.palmieri@st.com>

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