Important changes to repositories hosted on mbed.com
Mbed hosted mercurial repositories are deprecated and are due to be permanently deleted in July 2026.
To keep a copy of this software download the repository Zip archive or clone locally using Mercurial.
It is also possible to export all your personal repositories from the account settings page.
Fork of X_NUCLEO_IDB0XA1 by
source/BlueNRGGattServer.cpp@259:323f588e5f57, 2016-09-15 (annotated)
- 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?
User | Revision | Line number | New 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>© 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 | } |