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:21 2016 +0100
Branch:
70f819844d61400a7b6772dcc911a63fc73af09e
Revision:
259:323f588e5f57
Parent:
258:e5ef65120b06
Child:
260:e93cbde933ce
Sync with 70f819844d61400a7b6772dcc911a63fc73af09e

2016-07-08 12:18:26+01:00: Vincent Coubard
Fix ServiceInstantiation_test_xx

Fix the last handle set for characteristics
Fix discovery order.
From a user perspective, the service tree is traversed in deep.

The previous behavior was:

for service in services:
service_callback(callback)

for characteristic in characteristics:
characteristic_callback(characteristic)

The new behavior is:

for service in services:
service_callback(callback)
for characteristic in service.characteristics:
characteristic_callback(characteristic)

Reserve the valid count of attribute records when declaring a service.
Report error when it is not possible to add a service.

Who changed what in which revision?

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