1 /* att_internal.h - Attribute protocol handling */ 2 3 #include <zephyr/bluetooth/l2cap.h> 4 5 /* 6 * Copyright (c) 2015-2016 Intel Corporation 7 * 8 * SPDX-License-Identifier: Apache-2.0 9 */ 10 11 #define BT_EATT_PSM 0x27 12 #define BT_ATT_DEFAULT_LE_MTU 23 13 #define BT_ATT_TIMEOUT K_SECONDS(30) 14 15 /* Local ATT Rx MTU 16 * 17 * This is the local 'Client Rx MTU'/'Server Rx MTU'. Core v5.3 Vol 3 Part F 18 * 3.4.2.2 requires that they are equal. 19 * 20 * The local ATT Server Rx MTU is limited to BT_L2CAP_TX_MTU because the GATT 21 * long attribute read protocol (Core v5.3 Vol 3 Part G 4.8.3) treats the ATT 22 * MTU as a promise about the read size. This requires the server to negotiate 23 * the ATT_MTU down to what it is actually able to send. This will unfortunately 24 * also limit how much the client is allowed to send. 25 */ 26 #define BT_LOCAL_ATT_MTU_EATT MIN(BT_L2CAP_SDU_RX_MTU, BT_L2CAP_SDU_TX_MTU) 27 #define BT_LOCAL_ATT_MTU_UATT MIN(BT_L2CAP_RX_MTU, BT_L2CAP_TX_MTU) 28 29 #define BT_ATT_BUF_SIZE MAX(BT_LOCAL_ATT_MTU_UATT, BT_LOCAL_ATT_MTU_EATT) 30 31 struct bt_att_hdr { 32 uint8_t code; 33 } __packed; 34 35 #define BT_ATT_OP_ERROR_RSP 0x01 36 struct bt_att_error_rsp { 37 uint8_t request; 38 uint16_t handle; 39 uint8_t error; 40 } __packed; 41 42 #define BT_ATT_OP_MTU_REQ 0x02 43 struct bt_att_exchange_mtu_req { 44 uint16_t mtu; 45 } __packed; 46 47 #define BT_ATT_OP_MTU_RSP 0x03 48 struct bt_att_exchange_mtu_rsp { 49 uint16_t mtu; 50 } __packed; 51 52 /* Find Information Request */ 53 #define BT_ATT_OP_FIND_INFO_REQ 0x04 54 struct bt_att_find_info_req { 55 uint16_t start_handle; 56 uint16_t end_handle; 57 } __packed; 58 59 /* Format field values for BT_ATT_OP_FIND_INFO_RSP */ 60 #define BT_ATT_INFO_16 0x01 61 #define BT_ATT_INFO_128 0x02 62 63 struct bt_att_info_16 { 64 uint16_t handle; 65 uint16_t uuid; 66 } __packed; 67 68 struct bt_att_info_128 { 69 uint16_t handle; 70 uint8_t uuid[16]; 71 } __packed; 72 73 /* Find Information Response */ 74 #define BT_ATT_OP_FIND_INFO_RSP 0x05 75 struct bt_att_find_info_rsp { 76 uint8_t format; 77 uint8_t info[0]; 78 } __packed; 79 80 /* Find By Type Value Request */ 81 #define BT_ATT_OP_FIND_TYPE_REQ 0x06 82 struct bt_att_find_type_req { 83 uint16_t start_handle; 84 uint16_t end_handle; 85 uint16_t type; 86 uint8_t value[0]; 87 } __packed; 88 89 struct bt_att_handle_group { 90 uint16_t start_handle; 91 uint16_t end_handle; 92 } __packed; 93 94 /* Find By Type Value Response */ 95 #define BT_ATT_OP_FIND_TYPE_RSP 0x07 96 struct bt_att_find_type_rsp { 97 struct bt_att_handle_group list[0]; 98 } __packed; 99 100 /* Read By Type Request */ 101 #define BT_ATT_OP_READ_TYPE_REQ 0x08 102 struct bt_att_read_type_req { 103 uint16_t start_handle; 104 uint16_t end_handle; 105 uint8_t uuid[0]; 106 } __packed; 107 108 struct bt_att_data { 109 uint16_t handle; 110 uint8_t value[0]; 111 } __packed; 112 113 /* Read By Type Response */ 114 #define BT_ATT_OP_READ_TYPE_RSP 0x09 115 struct bt_att_read_type_rsp { 116 uint8_t len; 117 struct bt_att_data data[0]; 118 } __packed; 119 120 /* Read Request */ 121 #define BT_ATT_OP_READ_REQ 0x0a 122 struct bt_att_read_req { 123 uint16_t handle; 124 } __packed; 125 126 /* Read Response */ 127 #define BT_ATT_OP_READ_RSP 0x0b 128 struct bt_att_read_rsp { 129 uint8_t value[0]; 130 } __packed; 131 132 /* Read Blob Request */ 133 #define BT_ATT_OP_READ_BLOB_REQ 0x0c 134 struct bt_att_read_blob_req { 135 uint16_t handle; 136 uint16_t offset; 137 } __packed; 138 139 /* Read Blob Response */ 140 #define BT_ATT_OP_READ_BLOB_RSP 0x0d 141 struct bt_att_read_blob_rsp { 142 uint8_t value[0]; 143 } __packed; 144 145 /* Read Multiple Request */ 146 #define BT_ATT_READ_MULT_MIN_LEN_REQ 0x04 147 148 #define BT_ATT_OP_READ_MULT_REQ 0x0e 149 struct bt_att_read_mult_req { 150 uint16_t handles[0]; 151 } __packed; 152 153 /* Read Multiple Response */ 154 #define BT_ATT_OP_READ_MULT_RSP 0x0f 155 struct bt_att_read_mult_rsp { 156 uint8_t value[0]; 157 } __packed; 158 159 /* Read by Group Type Request */ 160 #define BT_ATT_OP_READ_GROUP_REQ 0x10 161 struct bt_att_read_group_req { 162 uint16_t start_handle; 163 uint16_t end_handle; 164 uint8_t uuid[0]; 165 } __packed; 166 167 struct bt_att_group_data { 168 uint16_t start_handle; 169 uint16_t end_handle; 170 uint8_t value[0]; 171 } __packed; 172 173 /* Read by Group Type Response */ 174 #define BT_ATT_OP_READ_GROUP_RSP 0x11 175 struct bt_att_read_group_rsp { 176 uint8_t len; 177 struct bt_att_group_data data[0]; 178 } __packed; 179 180 /* Write Request */ 181 #define BT_ATT_OP_WRITE_REQ 0x12 182 struct bt_att_write_req { 183 uint16_t handle; 184 uint8_t value[0]; 185 } __packed; 186 187 /* Write Response */ 188 #define BT_ATT_OP_WRITE_RSP 0x13 189 190 /* Prepare Write Request */ 191 #define BT_ATT_OP_PREPARE_WRITE_REQ 0x16 192 struct bt_att_prepare_write_req { 193 uint16_t handle; 194 uint16_t offset; 195 uint8_t value[0]; 196 } __packed; 197 198 /* Prepare Write Respond */ 199 #define BT_ATT_OP_PREPARE_WRITE_RSP 0x17 200 struct bt_att_prepare_write_rsp { 201 uint16_t handle; 202 uint16_t offset; 203 uint8_t value[0]; 204 } __packed; 205 206 /* Execute Write Request */ 207 #define BT_ATT_FLAG_CANCEL 0x00 208 #define BT_ATT_FLAG_EXEC 0x01 209 210 #define BT_ATT_OP_EXEC_WRITE_REQ 0x18 211 struct bt_att_exec_write_req { 212 uint8_t flags; 213 } __packed; 214 215 /* Execute Write Response */ 216 #define BT_ATT_OP_EXEC_WRITE_RSP 0x19 217 218 /* Handle Value Notification */ 219 #define BT_ATT_OP_NOTIFY 0x1b 220 struct bt_att_notify { 221 uint16_t handle; 222 uint8_t value[0]; 223 } __packed; 224 225 /* Handle Value Indication */ 226 #define BT_ATT_OP_INDICATE 0x1d 227 struct bt_att_indicate { 228 uint16_t handle; 229 uint8_t value[0]; 230 } __packed; 231 232 /* Handle Value Confirm */ 233 #define BT_ATT_OP_CONFIRM 0x1e 234 235 struct bt_att_signature { 236 uint8_t value[12]; 237 } __packed; 238 239 #define BT_ATT_OP_READ_MULT_VL_REQ 0x20 240 struct bt_att_read_mult_vl_req { 241 uint16_t handles[0]; 242 } __packed; 243 244 /* Read Multiple Response */ 245 #define BT_ATT_OP_READ_MULT_VL_RSP 0x21 246 struct bt_att_read_mult_vl_rsp { 247 uint16_t len; 248 uint8_t value[0]; 249 } __packed; 250 251 /* Handle Multiple Value Notification */ 252 #define BT_ATT_OP_NOTIFY_MULT 0x23 253 struct bt_att_notify_mult { 254 uint16_t handle; 255 uint16_t len; 256 uint8_t value[0]; 257 } __packed; 258 259 /* Write Command */ 260 #define BT_ATT_OP_WRITE_CMD 0x52 261 struct bt_att_write_cmd { 262 uint16_t handle; 263 uint8_t value[0]; 264 } __packed; 265 266 /* Signed Write Command */ 267 #define BT_ATT_OP_SIGNED_WRITE_CMD 0xd2 268 struct bt_att_signed_write_cmd { 269 uint16_t handle; 270 uint8_t value[0]; 271 } __packed; 272 273 typedef void (*bt_att_func_t)(struct bt_conn *conn, uint8_t err, 274 const void *pdu, uint16_t length, 275 void *user_data); 276 277 typedef int (*bt_att_encode_t)(struct net_buf *buf, size_t len, 278 void *user_data); 279 280 /* ATT request context */ 281 struct bt_att_req { 282 sys_snode_t node; 283 bt_att_func_t func; 284 struct net_buf *buf; 285 #if defined(CONFIG_BT_SMP) 286 bt_att_encode_t encode; 287 uint8_t retrying : 1; 288 uint8_t att_op; 289 size_t len; 290 #endif /* CONFIG_BT_SMP */ 291 void *user_data; 292 }; 293 294 void att_sent(struct bt_conn *conn, void *user_data); 295 296 void bt_att_init(void); 297 uint16_t bt_att_get_mtu(struct bt_conn *conn); 298 struct net_buf *bt_att_create_pdu(struct bt_conn *conn, uint8_t op, 299 size_t len); 300 301 /* Allocate a new request */ 302 struct bt_att_req *bt_att_req_alloc(k_timeout_t timeout); 303 304 /* Free a request */ 305 void bt_att_req_free(struct bt_att_req *req); 306 307 /* Send ATT PDU over a connection */ 308 int bt_att_send(struct bt_conn *conn, struct net_buf *buf); 309 310 /* Send ATT Request over a connection */ 311 int bt_att_req_send(struct bt_conn *conn, struct bt_att_req *req); 312 313 /* Cancel ATT request */ 314 void bt_att_req_cancel(struct bt_conn *conn, struct bt_att_req *req); 315 316 /* Disconnect EATT channels */ 317 int bt_eatt_disconnect(struct bt_conn *conn); 318 319 /** @brief Find a pending ATT request by its user_data pointer. 320 * @param conn The connection the request was issued on. 321 * @param user_data The pointer value to look for. 322 * @return The found request. NULL if not found. 323 */ 324 struct bt_att_req *bt_att_find_req_by_user_data(struct bt_conn *conn, const void *user_data); 325 326 /* Checks if only the fixed ATT channel is connected */ 327 bool bt_att_fixed_chan_only(struct bt_conn *conn); 328 329 /* Clear the out of sync flag on all channels */ 330 void bt_att_clear_out_of_sync_sent(struct bt_conn *conn); 331 332 /* Check if BT_ATT_ERR_DB_OUT_OF_SYNC has been sent on the fixed ATT channel */ 333 bool bt_att_out_of_sync_sent_on_fixed(struct bt_conn *conn); 334 335 typedef void (*bt_gatt_complete_func_t) (struct bt_conn *conn, void *user_data); 336 void bt_att_set_tx_meta_data(struct net_buf *buf, bt_gatt_complete_func_t func, void *user_data, 337 enum bt_att_chan_opt chan_opt); 338 void bt_att_increment_tx_meta_data_attr_count(struct net_buf *buf, uint16_t attr_count); 339 340 bool bt_att_tx_meta_data_match(const struct net_buf *buf, bt_gatt_complete_func_t func, 341 const void *user_data, enum bt_att_chan_opt chan_opt); 342 343 #if defined(CONFIG_BT_EATT) 344 #define BT_ATT_CHAN_OPT(_params) (_params)->chan_opt 345 #else 346 #define BT_ATT_CHAN_OPT(_params) BT_ATT_CHAN_OPT_UNENHANCED_ONLY 347 #endif /* CONFIG_BT_EATT */ 348 349 bool bt_att_chan_opt_valid(struct bt_conn *conn, enum bt_att_chan_opt chan_opt); 350