Fork of ble-x-nucleo-idb0xa1 with changes required by BleStarMbed

Dependents:   ble-star-mbed

Committer:
lorevee
Date:
Tue Feb 20 11:07:16 2018 +0000
Revision:
0:ac0b0725c6fa
Initial commit

Who changed what in which revision?

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