1 /* 2 * Copyright (C) 2017 C-SKY Microsystems Co., Ltd. All rights reserved. 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17 #ifndef __GATT_H__ 18 #define __GATT_H__ 19 20 #include <aos/uuid.h> 21 #include <ble_config.h> 22 23 #define ARRAY_SIZES(array) (sizeof(array)/sizeof(array[0])) 24 25 #ifdef __cplusplus 26 extern "C" { 27 #endif 28 29 typedef enum { 30 CCC_VALUE_NONE = 0, 31 CCC_VALUE_NOTIFY = 1, 32 CCC_VALUE_INDICATE = 2 33 } ccc_value_en; 34 35 /* GATT attribute permission bit field values */ 36 typedef enum { 37 /** No operations supported, e.g. for notify-only */ 38 GATT_PERM_NONE = 0, 39 40 /** Attribute read permission. */ 41 GATT_PERM_READ = BLE_BIT(0), 42 43 /** Attribute write permission. */ 44 GATT_PERM_WRITE = BLE_BIT(1), 45 46 /** Attribute read permission with encryption. 47 * 48 * If set, requires encryption for read access. 49 */ 50 GATT_PERM_READ_ENCRYPT = BLE_BIT(2), 51 52 /** Attribute write permission with encryption. 53 * 54 * If set, requires encryption for write access. 55 */ 56 GATT_PERM_WRITE_ENCRYPT = BLE_BIT(3), 57 58 /** Attribute read permission with authentication. 59 * 60 * If set, requires encryption using authenticated link-key for read 61 * access. 62 */ 63 GATT_PERM_READ_AUTHEN = BLE_BIT(4), 64 65 /** Attribute write permission with authentication. 66 * 67 * If set, requires encryption using authenticated link-key for write 68 * access. 69 */ 70 GATT_PERM_WRITE_AUTHEN = BLE_BIT(5), 71 72 /** Attribute prepare write permission. 73 * 74 * If set, allows prepare writes with use of GATT_WRITE_FLAG_PREPARE 75 * passed to write callback. 76 */ 77 GATT_PERM_PREPARE_WRITE = BLE_BIT(6), 78 } gatt_perm_en; 79 80 81 /* Characteristic Properties Bit field values */ 82 typedef enum { 83 /** @def BT_GATT_CHRC_BROADCAST 84 * @brief Characteristic broadcast property. 85 * 86 * If set, permits broadcasts of the Characteristic Value using Server 87 * Characteristic Configuration Descriptor. 88 */ 89 GATT_CHRC_PROP_BROADCAST = BLE_BIT(0), 90 /** @def BT_GATT_CHRC_READ 91 * @brief Characteristic read property. 92 * 93 * If set, permits reads of the Characteristic Value. 94 */ 95 GATT_CHRC_PROP_READ = BLE_BIT(1), 96 /** @def BT_GATT_CHRC_WRITE_WITHOUT_RESP 97 * @brief Characteristic write without response property. 98 * 99 * If set, permits write of the Characteristic Value without response. 100 */ 101 GATT_CHRC_PROP_WRITE_WITHOUT_RESP = BLE_BIT(2), 102 /** @def BT_GATT_CHRC_WRITE 103 * @brief Characteristic write with response property. 104 * 105 * If set, permits write of the Characteristic Value with response. 106 */ 107 GATT_CHRC_PROP_WRITE = BLE_BIT(3), 108 /** @def BT_GATT_CHRC_NOTIFY 109 * @brief Characteristic notify property. 110 * 111 * If set, permits notifications of a Characteristic Value without 112 * acknowledgment. 113 */ 114 GATT_CHRC_PROP_NOTIFY = BLE_BIT(4), 115 /** @def BT_GATT_CHRC_INDICATE 116 * @brief Characteristic indicate property. 117 * 118 * If set, permits indications of a Characteristic Value with acknowledgment. 119 */ 120 GATT_CHRC_PROP_INDICATE = BLE_BIT(5), 121 /** @def BT_GATT_CHRC_AUTH 122 * @brief Characteristic Authenticated Signed Writes property. 123 * 124 * If set, permits signed writes to the Characteristic Value. 125 */ 126 GATT_CHRC_PROP_AUTH = BLE_BIT(6), 127 /** @def BT_GATT_CHRC_EXT_PROP 128 * @brief Characteristic Extended Properties property. 129 * 130 * If set, additional characteristic properties are defined in the 131 * Characteristic Extended Properties Descriptor. 132 */ 133 GATT_CHRC_PROP_EXT_PROP = BLE_BIT(7), 134 } gatt_prop_en; 135 136 /* Error codes for Error response PDU */ 137 #define ATT_ERR_INVALID_HANDLE 0x01 138 #define ATT_ERR_READ_NOT_PERMITTED 0x02 139 #define ATT_ERR_WRITE_NOT_PERMITTED 0x03 140 #define ATT_ERR_INVALID_PDU 0x04 141 #define ATT_ERR_AUTHENTICATION 0x05 142 #define ATT_ERR_NOT_SUPPORTED 0x06 143 #define ATT_ERR_INVALID_OFFSET 0x07 144 #define ATT_ERR_AUTHORIZATION 0x08 145 #define ATT_ERR_PREPARE_QUEUE_FULL 0x09 146 #define ATT_ERR_ATTRIBUTE_NOT_FOUND 0x0a 147 #define ATT_ERR_ATTRIBUTE_NOT_LONG 0x0b 148 #define ATT_ERR_ENCRYPTION_KEY_SIZE 0x0c 149 #define ATT_ERR_INVALID_ATTRIBUTE_LEN 0x0d 150 #define ATT_ERR_UNLIKELY 0x0e 151 #define ATT_ERR_INSUFFICIENT_ENCRYPTION 0x0f 152 #define ATT_ERR_UNSUPPORTED_GROUP_TYPE 0x10 153 #define ATT_ERR_INSUFFICIENT_RESOURCES 0x11 154 155 typedef int (*char_read_func_t)(uint16_t conn_handle, uint16_t char_handle, void *buf, uint16_t len, uint16_t offset); 156 typedef int (*char_write_func_t)(uint16_t conn_handle, uint16_t char_handle, void *buf, uint16_t len, uint16_t offset); 157 typedef void (*char_ccc_change_func_t)(ccc_value_en value); 158 159 struct gatt_char_t { 160 161 /** Characteristic UUID. */ 162 const uuid_t *uuid; 163 /** Characteristic Value handle. */ 164 uint16_t value_handle; 165 /** Characteristic properties. */ 166 uint8_t properties; 167 }; 168 169 typedef struct _gatt_cep_t { 170 uint16_t ext_props; 171 } gatt_cep_t; 172 173 typedef struct _gatt_cud_t { 174 char *user_des; /* User Description */ 175 } gatt_cud_t; 176 177 typedef struct _gatt_cpf_t { 178 /** Format of the value of the characteristic */ 179 uint8_t format; 180 /** Exponent field to determine how the value of this characteristic is further formatted */ 181 int8_t exponent; 182 /** Unit of the characteristic */ 183 uint16_t unit; 184 /** Name space of the description */ 185 uint8_t name_space; 186 /** Description of the characteristic as defined in a higher layer profile */ 187 uint16_t description; 188 } gatt_cpf_t; 189 190 #if 0 191 typedef struct _gatt_att_t { 192 uuid_t *uuid; 193 194 uint8_t perm; /* for Characteristic Value Declaration*/ 195 196 union { 197 void *value; 198 gatt_char_t *char_def; 199 gatt_cep_t *cep; 200 gatt_cud_t *cud; 201 gatt_cpf_t *cpf; 202 }; 203 204 char_read_func_t read; 205 206 char_write_func_t write; 207 208 } gatt_att_t; 209 #endif 210 211 212 typedef struct _gatt_attr_t { 213 /** Attribute UUID */ 214 uuid_t *uuid; 215 216 char_read_func_t read; 217 218 char_write_func_t write; 219 220 /** Attribute user data */ 221 void *user_data; 222 /** Attribute handle */ 223 uint16_t handle; 224 /** Attribute permissions */ 225 uint8_t perm; 226 } gatt_attr_t; 227 228 typedef struct { 229 uint8_t val[6]; 230 } bt_addr; 231 232 typedef struct { 233 uint8_t type; 234 bt_addr a; 235 } bt_addr_le; 236 237 struct bt_gatt_ccc_cfg_t { 238 uint8_t id; 239 bt_addr_le peer; 240 uint16_t value; 241 }; 242 243 #define BT_RTL 244 struct bt_gatt_ccc_t { 245 #ifndef BT_RTL 246 struct bt_gatt_ccc_cfg_t cfg[CONFIG_BT_MAX_PAIRED + CONFIG_BT_MAX_CONN]; 247 #else 248 struct bt_gatt_ccc_cfg_t cfg[2]; 249 #endif 250 uint16_t value; 251 void (*cfg_changed)(const gatt_attr_t *attr, uint16_t value); 252 int (*cfg_write)(void *conn, gatt_attr_t *attr, uint16_t value); 253 int (*cfg_match)(void *conn, gatt_attr_t *attr); 254 }; 255 256 #define GATT_ATT_DEFINE(_uuid, _perm, _read, _write,_value) \ 257 { \ 258 .uuid = _uuid, \ 259 .perm = _perm, \ 260 .read = _read, \ 261 .write = _write, \ 262 .user_data =(void *){ _value}, \ 263 } 264 #define GATT_PRIMARY_SERVICE_DEFINE(_uuid) \ 265 GATT_ATT_DEFINE(UUID_GATT_PRIMARY, GATT_PERM_READ, NULL, NULL,_uuid) 266 267 #define GATT_SECONDARY_SERVICE_DEFINE(_uuid) \ 268 GATT_ATT_DEFINE(UUID_GATT_SECONDARY, GATT_PERM_READ, NULL, NULL, _uuid) 269 270 #define GATT_CHAR_DEFINE(_uuid, _props) \ 271 GATT_ATT_DEFINE(UUID_GATT_CHRC, GATT_PERM_READ, \ 272 NULL, NULL,(&(struct gatt_char_t){.uuid= _uuid,.value_handle = 0,.properties = _props,})) 273 274 #define GATT_CHAR_VAL_DEFINE(_uuid, _perm) \ 275 GATT_ATT_DEFINE(_uuid, _perm, NULL, NULL, NULL) 276 277 #define GATT_CHAR_DESCRIPTOR_DEFINE(_uuid, _perm) \ 278 GATT_ATT_DEFINE(_uuid, _perm, NULL, NULL, NULL) 279 280 #define GATT_CHAR_CCC_DEFINE() \ 281 GATT_ATT_DEFINE(UUID_GATT_CCC, GATT_PERM_READ | GATT_PERM_WRITE, \ 282 NULL, NULL,(&(struct bt_gatt_ccc_t){.cfg= {{0}}})) 283 284 #define GATT_CHAR_CUD_DEFINE(_value, _perm) \ 285 GATT_ATT_DEFINE(UUID_GATT_CUD, _perm, NULL, NULL,(&(gatt_cud_t) {.user_des = _value})) 286 287 #define GATT_CHAR_CPF_DEFINE(_value, _perm) \ 288 GATT_ATT_DEFINE(UUID_GATT_CPF, _perm, NULL, NULL,(&(gatt_cep_t) {.ext_props = _value})) 289 290 291 typedef enum { 292 GATT_SERVER_TYPE_PRIMARY = 0, 293 GATT_SERVER_TYPE_SECONDARY, 294 GATT_SERVER_TYPE_INCLUDE, 295 } gatt_service_type_en; 296 297 typedef struct _gatt_service_param_t { 298 uuid_t *uuid; 299 gatt_service_type_en type; 300 } gatt_service_param; 301 302 #if 0 303 typedef struct _gatt_char_param_t { 304 uuid_t *uuid; 305 void *value; 306 char_read_func_t read; 307 char_write_func_t write; 308 uint8_t props; 309 uint8_t perm; 310 } gatt_char_param; 311 312 typedef struct _gatt_char_des_param_t { 313 uuid_t *uuid; 314 void *value; 315 char_read_func_t read; 316 char_write_func_t write; 317 uint8_t perm; 318 } gatt_char_des_param_t; 319 320 #endif 321 322 typedef enum { 323 GATT_FIND_PRIMARY_SERVICE, 324 GATT_FIND_INC_SERVICE, 325 GATT_FIND_CHAR, 326 GATT_FIND_CHAR_DESCRIPTOR, 327 } gatt_discovery_type_en; 328 329 struct _snode_ { 330 struct _snode_ *next; 331 }; 332 333 typedef struct _snode_ sys_snode; 334 335 /** @brief GATT Service structure */ 336 typedef struct _gatt_service_ { 337 /** Service Attributes */ 338 struct bt_gatt_attr *attrs; 339 /** Service Attribute count */ 340 uint32_t attr_count; 341 sys_snode node; 342 } gatt_service; 343 344 345 int ble_stack_gatt_registe_service(gatt_service *s, gatt_attr_t attrs[], uint16_t attr_num); 346 347 int ble_stack_gatt_notificate(int16_t conn_handle, uint16_t char_handle, const uint8_t *data, uint16_t len); 348 int ble_stack_gatt_indicate(int16_t conn_handle, int16_t char_handle, const uint8_t *data, uint16_t len); 349 int ble_stack_gatt_mtu_get(int16_t conn_handle); 350 int ble_stack_gatt_mtu_exchange(int16_t conn_handle); 351 352 int ble_stack_gatt_service_discovery(int16_t conn_handle); 353 int ble_stack_gatt_discovery(int16_t conn_handle, gatt_discovery_type_en type, uuid_t *uuid, uint16_t start_handle, uint16_t end_handle); 354 #define ble_stack_gatt_discovery_all(conn_handle) \ 355 ble_stack_gatt_discovery(conn_handle, GATT_FIND_PRIMARY_SERVICE, 0, 0x0001, 0xffff) 356 357 #define ble_stack_gatt_discovery_primary(conn_handle, uuid, start_handle, end_handle) \ 358 ble_stack_gatt_discovery(conn_handle, GATT_FIND_PRIMARY_SERVICE, uuid, start_handle, end_handle) 359 360 #define ble_stack_gatt_discovery_include(conn_handle, uuid, start_handle, end_handle) \ 361 ble_stack_gatt_discovery(conn_handle, GATT_FIND_INC_SERVICE, uuid, start_handle, end_handle) 362 363 #define ble_stack_gatt_discovery_char_all(conn_handle, start_handle, end_handle) \ 364 ble_stack_gatt_discovery(conn_handle, GATT_FIND_CHAR, 0, start_handle, end_handle) 365 366 #define ble_stack_gatt_discovery_char(conn_handle, uuid, start_handle, end_handle) \ 367 ble_stack_gatt_discovery(conn_handle, GATT_FIND_CHAR, uuid, start_handle, end_handle) 368 369 #define ble_stack_gatt_discovery_descriptor(conn_handle, uuid,start_handle, end_handle) \ 370 ble_stack_gatt_discovery(conn_handle, GATT_FIND_CHAR_DESCRIPTOR, uuid, start_handle, end_handle) 371 372 #define ble_stack_gatt_discovery_descriptor_all(conn_handle, start_handle, end_handle) \ 373 ble_stack_gatt_discovery(conn_handle, GATT_FIND_CHAR_DESCRIPTOR, 0, start_handle, end_handle) 374 375 typedef enum { 376 GATT_WRITE, 377 GATT_WRITE_WITHOUT_RESPONSE, 378 GATT_WRITE_SINGED, 379 } gatt_write_en; 380 381 int ble_stack_gatt_write(int16_t conn_handle, uint16_t attr_handle, uint8_t *data, uint16_t len, uint16_t offset, gatt_write_en type); 382 383 #define ble_stack_gatt_write_response(conn_handle, attr_handle, data, len, offset) \ 384 ble_stack_gatt_write(conn_handle, attr_handle, (uint8_t *)data, len, offset, GATT_WRITE) 385 386 #define ble_stack_gatt_write_no_response(conn_handle, attr_handle, data, len, offset) \ 387 ble_stack_gatt_write(conn_handle, attr_handle, (uint8_t *)data, len, offset, GATT_WRITE_WITHOUT_RESPONSE) 388 389 #define ble_stack_gatt_write_signed(conn_handle, attr_handle, data, len, offset) \ 390 ble_stack_gatt_write(conn_handle, attr_handle, (uint8_t *)data, len, offset, GATT_WRITE_SINGED) 391 392 int ble_stack_gatt_read(int16_t conn_handle, uint16_t attr_handle, uint16_t offset); 393 int ble_stack_gatt_read_multiple(int16_t conn_handle, uint16_t attr_count, uint16_t attr_handle[]); 394 395 #ifdef __cplusplus 396 } 397 #endif 398 399 #endif /* __BLE_H__ */ 400 401