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:
Wolfgang Betz
Date:
Tue Oct 06 14:25:08 2015 +0200
Revision:
130:770ce14d3d15
Child:
132:51056160fa4a
Include mbed-classic version

Derived from
- repo (on Codex): gitolite@codex.cro.st.com:x-nucleodev/X-NUCLEO-IKC01A1-MBED.git
- branch: ble_wb
- SHA1 ID: 5ccc73e35868169e42132c0d1c056f908a6d70c0

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 ******************************************************************************
Wolfgang Betz 130:770ce14d3d15 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>
Wolfgang Betz 130:770ce14d3d15 32 */
Wolfgang Betz 130:770ce14d3d15 33
Wolfgang Betz 130:770ce14d3d15 34
Wolfgang Betz 130:770ce14d3d15 35 // ANDREA: Changed some types (e.g., tHalUint8 --> uint8_t)
Wolfgang Betz 130:770ce14d3d15 36
Wolfgang Betz 130:770ce14d3d15 37 /** @defgroup BlueNRGGATTSERVER
Wolfgang Betz 130:770ce14d3d15 38 * @brief BlueNRG BLE_API GattServer Adaptation
Wolfgang Betz 130:770ce14d3d15 39 * @{
Wolfgang Betz 130:770ce14d3d15 40 */
Wolfgang Betz 130:770ce14d3d15 41
Wolfgang Betz 130:770ce14d3d15 42 #include "BlueNRGGattServer.h"
Wolfgang Betz 130:770ce14d3d15 43 #include "mbed.h"
Wolfgang Betz 130:770ce14d3d15 44 #include "BlueNRGGap.h"
Wolfgang Betz 130:770ce14d3d15 45 #include "Utils.h"
Wolfgang Betz 130:770ce14d3d15 46
Wolfgang Betz 130:770ce14d3d15 47 /**************************************************************************/
Wolfgang Betz 130:770ce14d3d15 48 /*!
Wolfgang Betz 130:770ce14d3d15 49 @brief Adds a new service to the GATT table on the peripheral
Wolfgang Betz 130:770ce14d3d15 50
Wolfgang Betz 130:770ce14d3d15 51 @params[in] service
Wolfgang Betz 130:770ce14d3d15 52 Pointer to instance of the Gatt Server to add
Wolfgang Betz 130:770ce14d3d15 53
Wolfgang Betz 130:770ce14d3d15 54 @returns ble_error_t
Wolfgang Betz 130:770ce14d3d15 55
Wolfgang Betz 130:770ce14d3d15 56 @retval BLE_ERROR_NONE
Wolfgang Betz 130:770ce14d3d15 57 Everything executed properly
Wolfgang Betz 130:770ce14d3d15 58
Wolfgang Betz 130:770ce14d3d15 59 @section EXAMPLE
Wolfgang Betz 130:770ce14d3d15 60
Wolfgang Betz 130:770ce14d3d15 61 @code
Wolfgang Betz 130:770ce14d3d15 62
Wolfgang Betz 130:770ce14d3d15 63 @endcode
Wolfgang Betz 130:770ce14d3d15 64 */
Wolfgang Betz 130:770ce14d3d15 65 /**************************************************************************/
Wolfgang Betz 130:770ce14d3d15 66 ble_error_t BlueNRGGattServer::addService(GattService &service)
Wolfgang Betz 130:770ce14d3d15 67 {
Wolfgang Betz 130:770ce14d3d15 68 /* ToDo: Make sure we don't overflow the array, etc. */
Wolfgang Betz 130:770ce14d3d15 69 /* ToDo: Make sure this service UUID doesn't already exist (?) */
Wolfgang Betz 130:770ce14d3d15 70 /* ToDo: Basic validation */
Wolfgang Betz 130:770ce14d3d15 71
Wolfgang Betz 130:770ce14d3d15 72 tBleStatus ret;
Wolfgang Betz 130:770ce14d3d15 73 uint8_t type;
Wolfgang Betz 130:770ce14d3d15 74 uint16_t short_uuid;
Wolfgang Betz 130:770ce14d3d15 75 uint8_t primary_short_uuid[2];
Wolfgang Betz 130:770ce14d3d15 76 uint8_t primary_base_uuid[16];
Wolfgang Betz 130:770ce14d3d15 77 uint8_t char_base_uuid[16];
Wolfgang Betz 130:770ce14d3d15 78 const uint8_t *base_uuid;
Wolfgang Betz 130:770ce14d3d15 79 const uint8_t *base_char_uuid;
Wolfgang Betz 130:770ce14d3d15 80
Wolfgang Betz 130:770ce14d3d15 81 uint8_t charsCount = 0;
Wolfgang Betz 130:770ce14d3d15 82 uint8_t maxAttrRecords = 0;
Wolfgang Betz 130:770ce14d3d15 83
Wolfgang Betz 130:770ce14d3d15 84 type = (service.getUUID()).shortOrLong();
Wolfgang Betz 130:770ce14d3d15 85 DEBUG("AddService(): Type:%d\n\r", type);
Wolfgang Betz 130:770ce14d3d15 86
Wolfgang Betz 130:770ce14d3d15 87 /* Add the service to the BlueNRG */
Wolfgang Betz 130:770ce14d3d15 88 short_uuid = (service.getUUID()).getShortUUID();
Wolfgang Betz 130:770ce14d3d15 89 STORE_LE_16(primary_short_uuid, short_uuid);
Wolfgang Betz 130:770ce14d3d15 90
Wolfgang Betz 130:770ce14d3d15 91 if(type==UUID::UUID_TYPE_LONG) {
Wolfgang Betz 130:770ce14d3d15 92 base_uuid = (service.getUUID()).getBaseUUID();
Wolfgang Betz 130:770ce14d3d15 93
Wolfgang Betz 130:770ce14d3d15 94 COPY_UUID_128(primary_base_uuid, base_uuid[15],base_uuid[14],base_uuid[13],base_uuid[12],base_uuid[11],base_uuid[10],base_uuid[9],
Wolfgang Betz 130:770ce14d3d15 95 base_uuid[8],base_uuid[7],base_uuid[6],base_uuid[5],base_uuid[4],primary_short_uuid[1],primary_short_uuid[0],base_uuid[1],base_uuid[0]);
Wolfgang Betz 130:770ce14d3d15 96 }
Wolfgang Betz 130:770ce14d3d15 97
Wolfgang Betz 130:770ce14d3d15 98 charsCount = service.getCharacteristicCount();
Wolfgang Betz 130:770ce14d3d15 99 //1(service record)+2records*char+1record*char_desc
Wolfgang Betz 130:770ce14d3d15 100 maxAttrRecords = 1+3*charsCount;
Wolfgang Betz 130:770ce14d3d15 101
Wolfgang Betz 130:770ce14d3d15 102 if(type==UUID::UUID_TYPE_SHORT) {
Wolfgang Betz 130:770ce14d3d15 103 ret = aci_gatt_add_serv(UUID_TYPE_16,
Wolfgang Betz 130:770ce14d3d15 104 primary_short_uuid,
Wolfgang Betz 130:770ce14d3d15 105 PRIMARY_SERVICE,
Wolfgang Betz 130:770ce14d3d15 106 maxAttrRecords/*7*/,
Wolfgang Betz 130:770ce14d3d15 107 &servHandle);
Wolfgang Betz 130:770ce14d3d15 108 DEBUG("aci_gatt_add_serv UUID_TYPE_LONG ret=%d\n\r", ret);
Wolfgang Betz 130:770ce14d3d15 109 }
Wolfgang Betz 130:770ce14d3d15 110 else if(type==UUID::UUID_TYPE_LONG) {
Wolfgang Betz 130:770ce14d3d15 111 ret = aci_gatt_add_serv(UUID_TYPE_128,
Wolfgang Betz 130:770ce14d3d15 112 primary_base_uuid,
Wolfgang Betz 130:770ce14d3d15 113 PRIMARY_SERVICE,
Wolfgang Betz 130:770ce14d3d15 114 maxAttrRecords/*7*/,
Wolfgang Betz 130:770ce14d3d15 115 &servHandle);
Wolfgang Betz 130:770ce14d3d15 116 DEBUG("aci_gatt_add_serv UUID_TYPE_LONG ret=%d\n\r", ret);
Wolfgang Betz 130:770ce14d3d15 117 }
Wolfgang Betz 130:770ce14d3d15 118
Wolfgang Betz 130:770ce14d3d15 119 service.setHandle(servHandle);
Wolfgang Betz 130:770ce14d3d15 120 //serviceHandleVector.push_back(servHandle);
Wolfgang Betz 130:770ce14d3d15 121 DEBUG("added servHandle handle =%u\n\r", servHandle);
Wolfgang Betz 130:770ce14d3d15 122 uint16_t bleCharacteristic;
Wolfgang Betz 130:770ce14d3d15 123
Wolfgang Betz 130:770ce14d3d15 124 //iterate to include all characteristics
Wolfgang Betz 130:770ce14d3d15 125 for (uint8_t i = 0; i < charsCount; i++) {
Wolfgang Betz 130:770ce14d3d15 126 GattCharacteristic *p_char = service.getCharacteristic(i);
Wolfgang Betz 130:770ce14d3d15 127 uint16_t char_uuid = (p_char->getValueAttribute().getUUID()).getShortUUID();
Wolfgang Betz 130:770ce14d3d15 128
Wolfgang Betz 130:770ce14d3d15 129 uint8_t int_8_uuid[2];
Wolfgang Betz 130:770ce14d3d15 130 STORE_LE_16(int_8_uuid, char_uuid);
Wolfgang Betz 130:770ce14d3d15 131
Wolfgang Betz 130:770ce14d3d15 132 if(type==UUID::UUID_TYPE_LONG) {
Wolfgang Betz 130:770ce14d3d15 133 base_char_uuid = (p_char->getValueAttribute().getUUID()).getBaseUUID();
Wolfgang Betz 130:770ce14d3d15 134
Wolfgang Betz 130:770ce14d3d15 135 COPY_UUID_128(char_base_uuid, base_char_uuid[15],base_char_uuid[14],base_char_uuid[13],base_char_uuid[12],base_char_uuid[11],base_char_uuid[10],base_char_uuid[9],
Wolfgang Betz 130:770ce14d3d15 136 base_char_uuid[8],base_char_uuid[7],base_char_uuid[6],base_char_uuid[5],base_char_uuid[4],int_8_uuid[1],int_8_uuid[0],base_char_uuid[1],base_char_uuid[0]);
Wolfgang Betz 130:770ce14d3d15 137 }
Wolfgang Betz 130:770ce14d3d15 138
Wolfgang Betz 130:770ce14d3d15 139 DEBUG("Char Properties 0x%x\n\r", p_char->getProperties());
Wolfgang Betz 130:770ce14d3d15 140 /*
Wolfgang Betz 130:770ce14d3d15 141 * Gatt_Evt_Mask -> HardCoded (0)
Wolfgang Betz 130:770ce14d3d15 142 * Encryption_Key_Size -> Hardcoded (16)
Wolfgang Betz 130:770ce14d3d15 143 * isVariable (variable length value field) -> Hardcoded (1)
Wolfgang Betz 130:770ce14d3d15 144 */
Wolfgang Betz 130:770ce14d3d15 145 uint8_t Gatt_Evt_Mask = 0x0;
Wolfgang Betz 130:770ce14d3d15 146
Wolfgang Betz 130:770ce14d3d15 147 if((p_char->getProperties() &
Wolfgang Betz 130:770ce14d3d15 148 (GattCharacteristic::BLE_GATT_CHAR_PROPERTIES_WRITE_WITHOUT_RESPONSE|
Wolfgang Betz 130:770ce14d3d15 149 GattCharacteristic::BLE_GATT_CHAR_PROPERTIES_WRITE))) {
Wolfgang Betz 130:770ce14d3d15 150 DEBUG("Setting up Gatt GATT_NOTIFY_ATTRIBUTE_WRITE Mask\n\r");
Wolfgang Betz 130:770ce14d3d15 151 Gatt_Evt_Mask = Gatt_Evt_Mask | GATT_NOTIFY_ATTRIBUTE_WRITE;
Wolfgang Betz 130:770ce14d3d15 152 }
Wolfgang Betz 130:770ce14d3d15 153 if((p_char->getProperties() &
Wolfgang Betz 130:770ce14d3d15 154 (GattCharacteristic::BLE_GATT_CHAR_PROPERTIES_READ|
Wolfgang Betz 130:770ce14d3d15 155 GattCharacteristic::BLE_GATT_CHAR_PROPERTIES_NOTIFY| GattCharacteristic::BLE_GATT_CHAR_PROPERTIES_INDICATE))) {
Wolfgang Betz 130:770ce14d3d15 156 DEBUG("Setting up Gatt GATT_NOTIFY_READ_REQ_AND_WAIT_FOR_APPL_RESP Mask\n\r");
Wolfgang Betz 130:770ce14d3d15 157 Gatt_Evt_Mask = Gatt_Evt_Mask | GATT_NOTIFY_READ_REQ_AND_WAIT_FOR_APPL_RESP;
Wolfgang Betz 130:770ce14d3d15 158 } //This will support also GATT_SERVER_ATTR_READ_WRITE since it will be covered by previous if() check.
Wolfgang Betz 130:770ce14d3d15 159
Wolfgang Betz 130:770ce14d3d15 160 if(type==UUID::UUID_TYPE_SHORT) {
Wolfgang Betz 130:770ce14d3d15 161 ret = aci_gatt_add_char(service.getHandle(),
Wolfgang Betz 130:770ce14d3d15 162 UUID_TYPE_16,
Wolfgang Betz 130:770ce14d3d15 163 int_8_uuid,
Wolfgang Betz 130:770ce14d3d15 164 p_char->getValueAttribute().getMaxLength() /*2*/ /*Value Length*/,
Wolfgang Betz 130:770ce14d3d15 165 p_char->getProperties(),
Wolfgang Betz 130:770ce14d3d15 166 ATTR_PERMISSION_NONE,
Wolfgang Betz 130:770ce14d3d15 167 Gatt_Evt_Mask /*Gatt_Evt_Mask*/,
Wolfgang Betz 130:770ce14d3d15 168 16 /*Encryption_Key_Size*/,
Wolfgang Betz 130:770ce14d3d15 169 1 /*isVariable*/,
Wolfgang Betz 130:770ce14d3d15 170 &bleCharacteristic);
Wolfgang Betz 130:770ce14d3d15 171
Wolfgang Betz 130:770ce14d3d15 172 DEBUG("aci_gatt_add_char UUID_TYPE_16 props=%d MaxLength=%d ret=%d\n\r", p_char->getProperties(), p_char->getValueAttribute().getMaxLength(), ret);
Wolfgang Betz 130:770ce14d3d15 173
Wolfgang Betz 130:770ce14d3d15 174 } else if(type==UUID::UUID_TYPE_LONG) {
Wolfgang Betz 130:770ce14d3d15 175 ret = aci_gatt_add_char(service.getHandle(),
Wolfgang Betz 130:770ce14d3d15 176 UUID_TYPE_128,
Wolfgang Betz 130:770ce14d3d15 177 char_base_uuid,
Wolfgang Betz 130:770ce14d3d15 178 p_char->getValueAttribute().getMaxLength() /*2*/ /*Value Length*/,
Wolfgang Betz 130:770ce14d3d15 179 p_char->getProperties(),
Wolfgang Betz 130:770ce14d3d15 180 ATTR_PERMISSION_NONE,
Wolfgang Betz 130:770ce14d3d15 181 Gatt_Evt_Mask /*Gatt_Evt_Mask*/,
Wolfgang Betz 130:770ce14d3d15 182 16 /*Encryption_Key_Size*/,
Wolfgang Betz 130:770ce14d3d15 183 1 /*isVariable*/,
Wolfgang Betz 130:770ce14d3d15 184 &bleCharacteristic);
Wolfgang Betz 130:770ce14d3d15 185
Wolfgang Betz 130:770ce14d3d15 186 DEBUG("aci_gatt_add_char UUID_TYPE_128 props=%d MaxLength=%d ret=%d\n\r", p_char->getProperties(), p_char->getValueAttribute().getMaxLength(), ret);
Wolfgang Betz 130:770ce14d3d15 187 }
Wolfgang Betz 130:770ce14d3d15 188
Wolfgang Betz 130:770ce14d3d15 189 /* Update the characteristic handle */
Wolfgang Betz 130:770ce14d3d15 190 //uint16_t charHandle = characteristicCount;
Wolfgang Betz 130:770ce14d3d15 191
Wolfgang Betz 130:770ce14d3d15 192 bleCharHanldeMap.insert(std::pair<uint16_t, uint16_t>(bleCharacteristic, servHandle));
Wolfgang Betz 130:770ce14d3d15 193
Wolfgang Betz 130:770ce14d3d15 194 p_characteristics[characteristicCount++] = p_char;
Wolfgang Betz 130:770ce14d3d15 195 p_char->getValueAttribute().setHandle(bleCharacteristic); //Set the characteristic count as the corresponding char handle
Wolfgang Betz 130:770ce14d3d15 196 DEBUG("added bleCharacteristic handle =%u\n\r", bleCharacteristic);
Wolfgang Betz 130:770ce14d3d15 197
Wolfgang Betz 130:770ce14d3d15 198 if ((p_char->getValueAttribute().getValuePtr() != NULL) && (p_char->getValueAttribute().getInitialLength() > 0)) {
Wolfgang Betz 130:770ce14d3d15 199 write(p_char->getValueAttribute().getHandle(), p_char->getValueAttribute().getValuePtr(), p_char->getValueAttribute().getInitialLength(), false /* localOnly */);
Wolfgang Betz 130:770ce14d3d15 200 }
Wolfgang Betz 130:770ce14d3d15 201
Wolfgang Betz 130:770ce14d3d15 202 // add descriptors now
Wolfgang Betz 130:770ce14d3d15 203 uint16_t descHandle = 0;
Wolfgang Betz 130:770ce14d3d15 204 DEBUG("p_char->getDescriptorCount()=%d\n\r", p_char->getDescriptorCount());
Wolfgang Betz 130:770ce14d3d15 205
Wolfgang Betz 130:770ce14d3d15 206 for(uint8_t descIndex=0; descIndex<p_char->getDescriptorCount(); descIndex++) {
Wolfgang Betz 130:770ce14d3d15 207 GattAttribute *descriptor = p_char->getDescriptor(descIndex);
Wolfgang Betz 130:770ce14d3d15 208 uint16_t shortUUID = descriptor->getUUID().getShortUUID();
Wolfgang Betz 130:770ce14d3d15 209 const uint8_t uuidArray[] = {(uint8_t)((shortUUID>>8)&0xFF), (uint8_t)((shortUUID&0xFF))};
Wolfgang Betz 130:770ce14d3d15 210 ret = aci_gatt_add_char_desc(service.getHandle(), p_char->getValueAttribute().getHandle(),
Wolfgang Betz 130:770ce14d3d15 211 CHAR_DESC_TYPE_16_BIT, uuidArray, descriptor->getMaxLength(), descriptor->getInitialLength(),
Wolfgang Betz 130:770ce14d3d15 212 descriptor->getValuePtr(), CHAR_DESC_SECURITY_PERMISSION, CHAR_DESC_ACCESS_PERMISSION, GATT_NOTIFY_ATTRIBUTE_WRITE,
Wolfgang Betz 130:770ce14d3d15 213 MIN_ENCRY_KEY_SIZE, CHAR_ATTRIBUTE_LEN_IS_FIXED, &descHandle);
Wolfgang Betz 130:770ce14d3d15 214 DEBUG("Adding Descriptor descriptor handle=%d ret=%d\n\r", descHandle, ret);
Wolfgang Betz 130:770ce14d3d15 215 if(ret==(tBleStatus)0) {
Wolfgang Betz 130:770ce14d3d15 216 DEBUG("Descriptor added successfully, descriptor handle=%d\n\r", descHandle);
Wolfgang Betz 130:770ce14d3d15 217 descriptor->setHandle(descHandle);
Wolfgang Betz 130:770ce14d3d15 218 }
Wolfgang Betz 130:770ce14d3d15 219 }
Wolfgang Betz 130:770ce14d3d15 220
Wolfgang Betz 130:770ce14d3d15 221 }
Wolfgang Betz 130:770ce14d3d15 222
Wolfgang Betz 130:770ce14d3d15 223 serviceCount++;
Wolfgang Betz 130:770ce14d3d15 224
Wolfgang Betz 130:770ce14d3d15 225 //FIXME: There is no GattService pointer array in GattServer.
Wolfgang Betz 130:770ce14d3d15 226 // There should be one? (Only the user is aware of GattServices!) Report to forum.
Wolfgang Betz 130:770ce14d3d15 227
Wolfgang Betz 130:770ce14d3d15 228 return BLE_ERROR_NONE;
Wolfgang Betz 130:770ce14d3d15 229 }
Wolfgang Betz 130:770ce14d3d15 230
Wolfgang Betz 130:770ce14d3d15 231 /**************************************************************************/
Wolfgang Betz 130:770ce14d3d15 232 /*!
Wolfgang Betz 130:770ce14d3d15 233 @brief Reads the value of a characteristic, based on the service
Wolfgang Betz 130:770ce14d3d15 234 and characteristic index fields
Wolfgang Betz 130:770ce14d3d15 235
Wolfgang Betz 130:770ce14d3d15 236 @param[in] charHandle
Wolfgang Betz 130:770ce14d3d15 237 The handle of the GattCharacteristic to read from
Wolfgang Betz 130:770ce14d3d15 238 @param[in] buffer
Wolfgang Betz 130:770ce14d3d15 239 Buffer to hold the the characteristic's value
Wolfgang Betz 130:770ce14d3d15 240 (raw byte array in LSB format)
Wolfgang Betz 130:770ce14d3d15 241 @param[in] lengthP
Wolfgang Betz 130:770ce14d3d15 242 The number of bytes read into the buffer
Wolfgang Betz 130:770ce14d3d15 243
Wolfgang Betz 130:770ce14d3d15 244 @returns ble_error_t
Wolfgang Betz 130:770ce14d3d15 245
Wolfgang Betz 130:770ce14d3d15 246 @retval BLE_ERROR_NONE
Wolfgang Betz 130:770ce14d3d15 247 Everything executed properly
Wolfgang Betz 130:770ce14d3d15 248
Wolfgang Betz 130:770ce14d3d15 249 @section EXAMPLE
Wolfgang Betz 130:770ce14d3d15 250
Wolfgang Betz 130:770ce14d3d15 251 @code
Wolfgang Betz 130:770ce14d3d15 252
Wolfgang Betz 130:770ce14d3d15 253 @endcode
Wolfgang Betz 130:770ce14d3d15 254 */
Wolfgang Betz 130:770ce14d3d15 255 /**************************************************************************/
Wolfgang Betz 130:770ce14d3d15 256 ble_error_t BlueNRGGattServer::readValue(uint16_t charHandle, uint8_t buffer[], uint16_t *const lengthP)
Wolfgang Betz 130:770ce14d3d15 257 {
Wolfgang Betz 130:770ce14d3d15 258 DEBUG("ReadValue() Not Supported\n\r");
Wolfgang Betz 130:770ce14d3d15 259 return BLE_ERROR_NONE;
Wolfgang Betz 130:770ce14d3d15 260 }
Wolfgang Betz 130:770ce14d3d15 261
Wolfgang Betz 130:770ce14d3d15 262 /**************************************************************************/
Wolfgang Betz 130:770ce14d3d15 263 /*!
Wolfgang Betz 130:770ce14d3d15 264 @brief Updates the value of a characteristic, based on the service
Wolfgang Betz 130:770ce14d3d15 265 and characteristic index fields
Wolfgang Betz 130:770ce14d3d15 266
Wolfgang Betz 130:770ce14d3d15 267 @param[in] charHandle
Wolfgang Betz 130:770ce14d3d15 268 The handle of the GattCharacteristic to write to
Wolfgang Betz 130:770ce14d3d15 269 @param[in] buffer
Wolfgang Betz 130:770ce14d3d15 270 Data to use when updating the characteristic's value
Wolfgang Betz 130:770ce14d3d15 271 (raw byte array in LSB format)
Wolfgang Betz 130:770ce14d3d15 272 @param[in] len
Wolfgang Betz 130:770ce14d3d15 273 The number of bytes in buffer
Wolfgang Betz 130:770ce14d3d15 274
Wolfgang Betz 130:770ce14d3d15 275 @returns ble_error_t
Wolfgang Betz 130:770ce14d3d15 276
Wolfgang Betz 130:770ce14d3d15 277 @retval BLE_ERROR_NONE
Wolfgang Betz 130:770ce14d3d15 278 Everything executed properly
Wolfgang Betz 130:770ce14d3d15 279
Wolfgang Betz 130:770ce14d3d15 280 @section EXAMPLE
Wolfgang Betz 130:770ce14d3d15 281
Wolfgang Betz 130:770ce14d3d15 282 @code
Wolfgang Betz 130:770ce14d3d15 283
Wolfgang Betz 130:770ce14d3d15 284 @endcode
Wolfgang Betz 130:770ce14d3d15 285 */
Wolfgang Betz 130:770ce14d3d15 286 /**************************************************************************/
Wolfgang Betz 130:770ce14d3d15 287 // <<<ANDREA>>>
Wolfgang Betz 130:770ce14d3d15 288 ble_error_t BlueNRGGattServer::readValue(Gap::Handle_t connectionHandle, GattAttribute::Handle_t attributeHandle, uint8_t buffer[], uint16_t *lengthP) {
Wolfgang Betz 130:770ce14d3d15 289 // Empty by now
Wolfgang Betz 130:770ce14d3d15 290 return BLE_ERROR_NONE;
Wolfgang Betz 130:770ce14d3d15 291 }
Wolfgang Betz 130:770ce14d3d15 292
Wolfgang Betz 130:770ce14d3d15 293 ble_error_t BlueNRGGattServer::write(Gap::Handle_t connectionHandle, GattAttribute::Handle_t, const uint8_t[], uint16_t, bool localOnly) {
Wolfgang Betz 130:770ce14d3d15 294 // Empty by now
Wolfgang Betz 130:770ce14d3d15 295 return BLE_ERROR_NONE;
Wolfgang Betz 130:770ce14d3d15 296 }
Wolfgang Betz 130:770ce14d3d15 297
Wolfgang Betz 130:770ce14d3d15 298 ble_error_t BlueNRGGattServer::write(GattAttribute::Handle_t charHandle, const uint8_t buffer[], uint16_t len, bool localOnly)
Wolfgang Betz 130:770ce14d3d15 299 {
Wolfgang Betz 130:770ce14d3d15 300 tBleStatus ret;
Wolfgang Betz 130:770ce14d3d15 301 //uint8_t buff[2];
Wolfgang Betz 130:770ce14d3d15 302
Wolfgang Betz 130:770ce14d3d15 303 DEBUG("updating bleCharacteristic charHandle =%u, corresponding serviceHanle= %u len=%d\n\r", charHandle, bleCharHanldeMap.find(charHandle)->second, len);
Wolfgang Betz 130:770ce14d3d15 304 /*
Wolfgang Betz 130:770ce14d3d15 305 for(int i=0; i<len; i++) {
Wolfgang Betz 130:770ce14d3d15 306 DEBUG("buffer[%d]=%d\n\r", i, buffer[i]);
Wolfgang Betz 130:770ce14d3d15 307 }
Wolfgang Betz 130:770ce14d3d15 308 */
Wolfgang Betz 130:770ce14d3d15 309 ret = aci_gatt_update_char_value(bleCharHanldeMap.find(charHandle)->second, charHandle, 0, len, buffer);
Wolfgang Betz 130:770ce14d3d15 310
Wolfgang Betz 130:770ce14d3d15 311 if (ret != BLE_STATUS_SUCCESS){
Wolfgang Betz 130:770ce14d3d15 312 DEBUG("Error while updating characteristic (ret=0x%x).\n\r", ret) ;
Wolfgang Betz 130:770ce14d3d15 313 return BLE_ERROR_PARAM_OUT_OF_RANGE ; //Not correct Error Value
Wolfgang Betz 130:770ce14d3d15 314 //FIXME: Define Error values equivalent to BlueNRG Error Codes.
Wolfgang Betz 130:770ce14d3d15 315 }
Wolfgang Betz 130:770ce14d3d15 316
Wolfgang Betz 130:770ce14d3d15 317 //Generate Data Sent Event Here? (GattServerEvents::GATT_EVENT_DATA_SENT) //FIXME: Is this correct?
Wolfgang Betz 130:770ce14d3d15 318 //Check if characteristic property is NOTIFY|INDICATE, if yes generate event
Wolfgang Betz 130:770ce14d3d15 319 GattCharacteristic *p_char = BlueNRGGattServer::getInstance().getCharacteristicFromHandle(charHandle);
Wolfgang Betz 130:770ce14d3d15 320 if(p_char->getProperties() & (GattCharacteristic::BLE_GATT_CHAR_PROPERTIES_NOTIFY
Wolfgang Betz 130:770ce14d3d15 321 | GattCharacteristic::BLE_GATT_CHAR_PROPERTIES_INDICATE)) {
Wolfgang Betz 130:770ce14d3d15 322 DEBUG("Generate event after updating\n\r");
Wolfgang Betz 130:770ce14d3d15 323 BlueNRGGattServer::getInstance().handleEvent(GattServerEvents::GATT_EVENT_DATA_SENT, charHandle);
Wolfgang Betz 130:770ce14d3d15 324 }
Wolfgang Betz 130:770ce14d3d15 325
Wolfgang Betz 130:770ce14d3d15 326 return BLE_ERROR_NONE;
Wolfgang Betz 130:770ce14d3d15 327 }
Wolfgang Betz 130:770ce14d3d15 328
Wolfgang Betz 130:770ce14d3d15 329 /**************************************************************************/
Wolfgang Betz 130:770ce14d3d15 330 /*!
Wolfgang Betz 130:770ce14d3d15 331 @brief Reads a value according to the handle provided
Wolfgang Betz 130:770ce14d3d15 332
Wolfgang Betz 130:770ce14d3d15 333 @param[in] charHandle
Wolfgang Betz 130:770ce14d3d15 334 The handle of the GattCharacteristic to read from
Wolfgang Betz 130:770ce14d3d15 335
Wolfgang Betz 130:770ce14d3d15 336 @returns ble_error_t
Wolfgang Betz 130:770ce14d3d15 337
Wolfgang Betz 130:770ce14d3d15 338 @retval BLE_ERROR_NONE
Wolfgang Betz 130:770ce14d3d15 339 Everything executed properly
Wolfgang Betz 130:770ce14d3d15 340
Wolfgang Betz 130:770ce14d3d15 341 @section EXAMPLE
Wolfgang Betz 130:770ce14d3d15 342
Wolfgang Betz 130:770ce14d3d15 343 @code
Wolfgang Betz 130:770ce14d3d15 344
Wolfgang Betz 130:770ce14d3d15 345 @endcode
Wolfgang Betz 130:770ce14d3d15 346 */
Wolfgang Betz 130:770ce14d3d15 347 /**************************************************************************/
Wolfgang Betz 130:770ce14d3d15 348 ble_error_t BlueNRGGattServer::Read_Request_CB(uint16_t handle)
Wolfgang Betz 130:770ce14d3d15 349 {
Wolfgang Betz 130:770ce14d3d15 350 //signed short refvalue;
Wolfgang Betz 130:770ce14d3d15 351 uint16_t gapConnectionHandle = BlueNRGGap::getInstance().getConnectionHandle();
Wolfgang Betz 130:770ce14d3d15 352
Wolfgang Betz 130:770ce14d3d15 353 GattReadCallbackParams readParams;
Wolfgang Betz 130:770ce14d3d15 354 readParams.handle = handle;
Wolfgang Betz 130:770ce14d3d15 355
Wolfgang Betz 130:770ce14d3d15 356 //DEBUG("readParams.charHandle = %d\n\r", readParams.charHandle);
Wolfgang Betz 130:770ce14d3d15 357 HCIDataReadEvent(&readParams);
Wolfgang Betz 130:770ce14d3d15 358
Wolfgang Betz 130:770ce14d3d15 359 //EXIT:
Wolfgang Betz 130:770ce14d3d15 360 if(gapConnectionHandle != 0){
Wolfgang Betz 130:770ce14d3d15 361 //DEBUG("Calling aci_gatt_allow_read\n\r");
Wolfgang Betz 130:770ce14d3d15 362 aci_gatt_allow_read(gapConnectionHandle);
Wolfgang Betz 130:770ce14d3d15 363 }
Wolfgang Betz 130:770ce14d3d15 364
Wolfgang Betz 130:770ce14d3d15 365 return BLE_ERROR_NONE;
Wolfgang Betz 130:770ce14d3d15 366 }
Wolfgang Betz 130:770ce14d3d15 367
Wolfgang Betz 130:770ce14d3d15 368 /**************************************************************************/
Wolfgang Betz 130:770ce14d3d15 369 /*!
Wolfgang Betz 130:770ce14d3d15 370 @brief Returns the GattCharacteristic according to the handle provided
Wolfgang Betz 130:770ce14d3d15 371
Wolfgang Betz 130:770ce14d3d15 372 @param[in] charHandle
Wolfgang Betz 130:770ce14d3d15 373 The handle of the GattCharacteristic
Wolfgang Betz 130:770ce14d3d15 374
Wolfgang Betz 130:770ce14d3d15 375 @returns ble_error_t
Wolfgang Betz 130:770ce14d3d15 376
Wolfgang Betz 130:770ce14d3d15 377 @retval BLE_ERROR_NONE
Wolfgang Betz 130:770ce14d3d15 378 Everything executed properly
Wolfgang Betz 130:770ce14d3d15 379
Wolfgang Betz 130:770ce14d3d15 380 @section EXAMPLE
Wolfgang Betz 130:770ce14d3d15 381
Wolfgang Betz 130:770ce14d3d15 382 @code
Wolfgang Betz 130:770ce14d3d15 383
Wolfgang Betz 130:770ce14d3d15 384 @endcode
Wolfgang Betz 130:770ce14d3d15 385 */
Wolfgang Betz 130:770ce14d3d15 386 /**************************************************************************/
Wolfgang Betz 130:770ce14d3d15 387 GattCharacteristic* BlueNRGGattServer::getCharacteristicFromHandle(uint16_t attrHandle)
Wolfgang Betz 130:770ce14d3d15 388 {
Wolfgang Betz 130:770ce14d3d15 389 GattCharacteristic *p_char = NULL;
Wolfgang Betz 130:770ce14d3d15 390 int i;
Wolfgang Betz 130:770ce14d3d15 391 uint16_t handle, handle_1;
Wolfgang Betz 130:770ce14d3d15 392
Wolfgang Betz 130:770ce14d3d15 393 DEBUG("BlueNRGGattServer::getCharacteristicFromHandle()>>Attribute Handle received %d\n\r",attrHandle);
Wolfgang Betz 130:770ce14d3d15 394 for(i=0; i<characteristicCount; i++)
Wolfgang Betz 130:770ce14d3d15 395 {
Wolfgang Betz 130:770ce14d3d15 396 handle = p_characteristics[i]->getValueAttribute().getHandle();
Wolfgang Betz 130:770ce14d3d15 397 DEBUG("handle(%d)=%d\n\r", i, handle);
Wolfgang Betz 130:770ce14d3d15 398 if(i==characteristicCount-1)//Last Characteristic check
Wolfgang Betz 130:770ce14d3d15 399 {
Wolfgang Betz 130:770ce14d3d15 400 if(attrHandle>=handle)
Wolfgang Betz 130:770ce14d3d15 401 {
Wolfgang Betz 130:770ce14d3d15 402 p_char = p_characteristics[i];
Wolfgang Betz 130:770ce14d3d15 403 DEBUG("Found Characteristic Properties 0x%x (handle=%d)\n\r",p_char->getProperties(), handle);
Wolfgang Betz 130:770ce14d3d15 404 break;
Wolfgang Betz 130:770ce14d3d15 405 }
Wolfgang Betz 130:770ce14d3d15 406 }
Wolfgang Betz 130:770ce14d3d15 407 else {
Wolfgang Betz 130:770ce14d3d15 408 handle_1 = p_characteristics[i+1]->getValueAttribute().getHandle();
Wolfgang Betz 130:770ce14d3d15 409 //Testing if attribute handle is between two Characteristic Handles
Wolfgang Betz 130:770ce14d3d15 410 if(attrHandle>=handle && attrHandle<handle_1)
Wolfgang Betz 130:770ce14d3d15 411 {
Wolfgang Betz 130:770ce14d3d15 412 p_char = p_characteristics[i];
Wolfgang Betz 130:770ce14d3d15 413 DEBUG("Found Characteristic Properties 0x%x (handle=%d handle_1=%d)\n\r",p_char->getProperties(), handle, handle_1);
Wolfgang Betz 130:770ce14d3d15 414 break;
Wolfgang Betz 130:770ce14d3d15 415 } else continue;
Wolfgang Betz 130:770ce14d3d15 416 }
Wolfgang Betz 130:770ce14d3d15 417 }
Wolfgang Betz 130:770ce14d3d15 418
Wolfgang Betz 130:770ce14d3d15 419 return p_char;
Wolfgang Betz 130:770ce14d3d15 420 }
Wolfgang Betz 130:770ce14d3d15 421
Wolfgang Betz 130:770ce14d3d15 422 void BlueNRGGattServer::HCIDataWrittenEvent(const GattWriteCallbackParams *params) {
Wolfgang Betz 130:770ce14d3d15 423 this->handleDataWrittenEvent(params);
Wolfgang Betz 130:770ce14d3d15 424 }
Wolfgang Betz 130:770ce14d3d15 425
Wolfgang Betz 130:770ce14d3d15 426 void BlueNRGGattServer::HCIDataReadEvent(const GattReadCallbackParams *params) {
Wolfgang Betz 130:770ce14d3d15 427 DEBUG("Called HCIDataReadEvent\n\r");
Wolfgang Betz 130:770ce14d3d15 428 this->handleDataReadEvent(params);
Wolfgang Betz 130:770ce14d3d15 429 }
Wolfgang Betz 130:770ce14d3d15 430
Wolfgang Betz 130:770ce14d3d15 431 void BlueNRGGattServer::HCIEvent(GattServerEvents::gattEvent_e type, uint16_t charHandle) {
Wolfgang Betz 130:770ce14d3d15 432 this->handleEvent(type, charHandle);
Wolfgang Betz 130:770ce14d3d15 433 }
Wolfgang Betz 130:770ce14d3d15 434
Wolfgang Betz 130:770ce14d3d15 435 void BlueNRGGattServer::HCIDataSentEvent(unsigned count) {
Wolfgang Betz 130:770ce14d3d15 436 this->handleDataSentEvent(count);
Wolfgang Betz 130:770ce14d3d15 437 }
Wolfgang Betz 130:770ce14d3d15 438
Wolfgang Betz 130:770ce14d3d15 439
Wolfgang Betz 130:770ce14d3d15 440 ble_error_t BlueNRGGattServer::initializeGATTDatabase(void) {
Wolfgang Betz 130:770ce14d3d15 441 // <TODO>
Wolfgang Betz 130:770ce14d3d15 442 return (ble_error_t)0;
Wolfgang Betz 130:770ce14d3d15 443 }