1 /* 2 * Licensed to the Apache Software Foundation (ASF) under one 3 * or more contributor license agreements. See the NOTICE file 4 * distributed with this work for additional information 5 * regarding copyright ownership. The ASF licenses this file 6 * to you under the Apache License, Version 2.0 (the 7 * "License"); you may not use this file except in compliance 8 * with the License. You may obtain a copy of the License at 9 * 10 * http://www.apache.org/licenses/LICENSE-2.0 11 * 12 * Unless required by applicable law or agreed to in writing, 13 * software distributed under the License is distributed on an 14 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 15 * KIND, either express or implied. See the License for the 16 * specific language governing permissions and limitations 17 * under the License. 18 */ 19 20 #ifndef H_BLE_ATT_PRIV_ 21 #define H_BLE_ATT_PRIV_ 22 23 #include <inttypes.h> 24 #include "stats/stats.h" 25 #include "host/ble_att.h" 26 #include "host/ble_uuid.h" 27 #include "nimble/nimble_npl.h" 28 29 #ifdef __cplusplus 30 extern "C" { 31 #endif 32 33 struct os_mbuf; 34 struct ble_hs_conn; 35 struct ble_l2cap_chan; 36 struct ble_att_find_info_req; 37 struct ble_att_error_rsp; 38 struct ble_att_mtu_cmd; 39 struct ble_att_read_req; 40 struct ble_att_read_blob_req; 41 struct ble_att_read_type_req; 42 struct ble_att_read_group_type_req; 43 struct ble_att_read_group_type_rsp; 44 struct ble_att_find_type_value_req; 45 struct ble_att_write_req; 46 struct ble_att_prep_write_cmd; 47 struct ble_att_exec_write_req; 48 struct ble_att_notify_req; 49 struct ble_att_indicate_req; 50 51 STATS_SECT_START(ble_att_stats) 52 STATS_SECT_ENTRY(error_rsp_rx) 53 STATS_SECT_ENTRY(error_rsp_tx) 54 STATS_SECT_ENTRY(mtu_req_rx) 55 STATS_SECT_ENTRY(mtu_req_tx) 56 STATS_SECT_ENTRY(mtu_rsp_rx) 57 STATS_SECT_ENTRY(mtu_rsp_tx) 58 STATS_SECT_ENTRY(find_info_req_rx) 59 STATS_SECT_ENTRY(find_info_req_tx) 60 STATS_SECT_ENTRY(find_info_rsp_rx) 61 STATS_SECT_ENTRY(find_info_rsp_tx) 62 STATS_SECT_ENTRY(find_type_value_req_rx) 63 STATS_SECT_ENTRY(find_type_value_req_tx) 64 STATS_SECT_ENTRY(find_type_value_rsp_rx) 65 STATS_SECT_ENTRY(find_type_value_rsp_tx) 66 STATS_SECT_ENTRY(read_type_req_rx) 67 STATS_SECT_ENTRY(read_type_req_tx) 68 STATS_SECT_ENTRY(read_type_rsp_rx) 69 STATS_SECT_ENTRY(read_type_rsp_tx) 70 STATS_SECT_ENTRY(read_req_rx) 71 STATS_SECT_ENTRY(read_req_tx) 72 STATS_SECT_ENTRY(read_rsp_rx) 73 STATS_SECT_ENTRY(read_rsp_tx) 74 STATS_SECT_ENTRY(read_blob_req_rx) 75 STATS_SECT_ENTRY(read_blob_req_tx) 76 STATS_SECT_ENTRY(read_blob_rsp_rx) 77 STATS_SECT_ENTRY(read_blob_rsp_tx) 78 STATS_SECT_ENTRY(read_mult_req_rx) 79 STATS_SECT_ENTRY(read_mult_req_tx) 80 STATS_SECT_ENTRY(read_mult_rsp_rx) 81 STATS_SECT_ENTRY(read_mult_rsp_tx) 82 STATS_SECT_ENTRY(read_group_type_req_rx) 83 STATS_SECT_ENTRY(read_group_type_req_tx) 84 STATS_SECT_ENTRY(read_group_type_rsp_rx) 85 STATS_SECT_ENTRY(read_group_type_rsp_tx) 86 STATS_SECT_ENTRY(write_req_rx) 87 STATS_SECT_ENTRY(write_req_tx) 88 STATS_SECT_ENTRY(write_rsp_rx) 89 STATS_SECT_ENTRY(write_rsp_tx) 90 STATS_SECT_ENTRY(prep_write_req_rx) 91 STATS_SECT_ENTRY(prep_write_req_tx) 92 STATS_SECT_ENTRY(prep_write_rsp_rx) 93 STATS_SECT_ENTRY(prep_write_rsp_tx) 94 STATS_SECT_ENTRY(exec_write_req_rx) 95 STATS_SECT_ENTRY(exec_write_req_tx) 96 STATS_SECT_ENTRY(exec_write_rsp_rx) 97 STATS_SECT_ENTRY(exec_write_rsp_tx) 98 STATS_SECT_ENTRY(notify_req_rx) 99 STATS_SECT_ENTRY(notify_req_tx) 100 STATS_SECT_ENTRY(indicate_req_rx) 101 STATS_SECT_ENTRY(indicate_req_tx) 102 STATS_SECT_ENTRY(indicate_rsp_rx) 103 STATS_SECT_ENTRY(indicate_rsp_tx) 104 STATS_SECT_ENTRY(write_cmd_rx) 105 STATS_SECT_ENTRY(write_cmd_tx) 106 STATS_SECT_END 107 extern STATS_SECT_DECL(ble_att_stats) ble_att_stats; 108 109 struct ble_att_prep_entry { 110 SLIST_ENTRY(ble_att_prep_entry) bape_next; 111 uint16_t bape_handle; 112 uint16_t bape_offset; 113 114 /* XXX: This is wasteful; we should use one mbuf chain for the entire 115 * prepared write, and compress the data into as few mbufs as possible. 116 */ 117 struct os_mbuf *bape_value; 118 }; 119 120 SLIST_HEAD(ble_att_prep_entry_list, ble_att_prep_entry); 121 122 struct ble_att_svr_conn { 123 /** This list is sorted by attribute handle ID. */ 124 struct ble_att_prep_entry_list basc_prep_list; 125 ble_npl_time_t basc_prep_timeout_at; 126 }; 127 128 /** 129 * Handles a host attribute request. 130 * 131 * @param entry The host attribute being requested. 132 * @param op The operation being performed on the attribute. 133 * @param arg The request data associated with that host 134 * attribute. 135 * 136 * @return 0 on success; 137 * One of the BLE_ATT_ERR_[...] codes on 138 * failure. 139 */ 140 typedef int ble_att_svr_access_fn(uint16_t conn_handle, uint16_t attr_handle, 141 uint8_t op, uint16_t offset, 142 struct os_mbuf **om, void *arg); 143 144 int ble_att_svr_register(const ble_uuid_t *uuid, uint8_t flags, 145 uint8_t min_key_size, uint16_t *handle_id, 146 ble_att_svr_access_fn *cb, void *cb_arg); 147 148 struct ble_att_svr_entry { 149 STAILQ_ENTRY(ble_att_svr_entry) ha_next; 150 151 const ble_uuid_t *ha_uuid; 152 uint8_t ha_flags; 153 uint8_t ha_min_key_size; 154 uint16_t ha_handle_id; 155 ble_att_svr_access_fn *ha_cb; 156 void *ha_cb_arg; 157 }; 158 159 SLIST_HEAD(ble_att_clt_entry_list, ble_att_clt_entry); 160 161 /*** @gen */ 162 163 struct ble_l2cap_chan *ble_att_create_chan(uint16_t conn_handle); 164 int ble_att_conn_chan_find(uint16_t conn_handle, struct ble_hs_conn **out_conn, 165 struct ble_l2cap_chan **out_chan); 166 void ble_att_inc_tx_stat(uint8_t att_op); 167 void ble_att_truncate_to_mtu(const struct ble_l2cap_chan *att_chan, 168 struct os_mbuf *txom); 169 void ble_att_set_peer_mtu(struct ble_l2cap_chan *chan, uint16_t peer_mtu); 170 uint16_t ble_att_chan_mtu(const struct ble_l2cap_chan *chan); 171 int ble_att_init(void); 172 173 #define BLE_ATT_LOG_CMD(is_tx, cmd_name, conn_handle, log_cb, cmd) \ 174 BLE_HS_LOG_CMD((is_tx), "att", (cmd_name), (conn_handle), (log_cb), (cmd)) 175 176 #define BLE_ATT_LOG_EMPTY_CMD(is_tx, cmd_name, conn_handle) \ 177 BLE_HS_LOG_EMPTY_CMD((is_tx), "att", (cmd_name), (conn_handle)) 178 179 /*** @svr */ 180 181 int ble_att_svr_start(void); 182 183 struct ble_att_svr_entry * 184 ble_att_svr_find_by_uuid(struct ble_att_svr_entry *start_at, 185 const ble_uuid_t *uuid, 186 uint16_t end_handle); 187 uint16_t ble_att_svr_prev_handle(void); 188 int ble_att_svr_rx_mtu(uint16_t conn_handle, struct os_mbuf **rxom); 189 struct ble_att_svr_entry *ble_att_svr_find_by_handle(uint16_t handle_id); 190 int32_t ble_att_svr_ticks_until_tmo(const struct ble_att_svr_conn *svr, 191 ble_npl_time_t now); 192 int ble_att_svr_rx_find_info(uint16_t conn_handle, struct os_mbuf **rxom); 193 int ble_att_svr_rx_find_type_value(uint16_t conn_handle, 194 struct os_mbuf **rxom); 195 int ble_att_svr_rx_read_type(uint16_t conn_handle, 196 struct os_mbuf **rxom); 197 int ble_att_svr_rx_read_group_type(uint16_t conn_handle, 198 struct os_mbuf **rxom); 199 int ble_att_svr_rx_read(uint16_t conn_handle, 200 struct os_mbuf **rxom); 201 int ble_att_svr_rx_read_blob(uint16_t conn_handle, 202 struct os_mbuf **rxom); 203 int ble_att_svr_rx_read_mult(uint16_t conn_handle, 204 struct os_mbuf **rxom); 205 int ble_att_svr_rx_write(uint16_t conn_handle, 206 struct os_mbuf **rxom); 207 int ble_att_svr_rx_write_no_rsp(uint16_t conn_handle, struct os_mbuf **rxom); 208 int ble_att_svr_rx_prep_write(uint16_t conn_handle, 209 struct os_mbuf **rxom); 210 int ble_att_svr_rx_exec_write(uint16_t conn_handle, 211 struct os_mbuf **rxom); 212 int ble_att_svr_rx_notify(uint16_t conn_handle, 213 struct os_mbuf **rxom); 214 int ble_att_svr_rx_indicate(uint16_t conn_handle, 215 struct os_mbuf **rxom); 216 void ble_att_svr_prep_clear(struct ble_att_prep_entry_list *prep_list); 217 int ble_att_svr_read_handle(uint16_t conn_handle, uint16_t attr_handle, 218 uint16_t offset, struct os_mbuf *om, 219 uint8_t *out_att_err); 220 void ble_att_svr_reset(void); 221 int ble_att_svr_init(void); 222 223 void ble_att_svr_hide_range(uint16_t start_handle, uint16_t end_handle); 224 void ble_att_svr_restore_range(uint16_t start_handle, uint16_t end_handle); 225 226 int ble_att_svr_tx_error_rsp(uint16_t conn_handle, struct os_mbuf *txom, 227 uint8_t req_op, uint16_t handle, 228 uint8_t error_code); 229 /*** $clt */ 230 231 /** An information-data entry in a find information response. */ 232 struct ble_att_find_info_idata { 233 uint16_t attr_handle; 234 ble_uuid_any_t uuid; 235 }; 236 237 /** A handles-information entry in a find by type value response. */ 238 struct ble_att_find_type_value_hinfo { 239 uint16_t attr_handle; 240 uint16_t group_end_handle; 241 }; 242 243 /** An attribute-data entry in a read by type response. */ 244 struct ble_att_read_type_adata { 245 uint16_t att_handle; 246 int value_len; 247 uint8_t *value; 248 249 }; 250 251 /** An attribute-data entry in a read by group type response. */ 252 struct ble_att_read_group_type_adata { 253 uint16_t att_handle; 254 uint16_t end_group_handle; 255 int value_len; 256 uint8_t *value; 257 }; 258 259 int ble_att_clt_rx_error(uint16_t conn_handle, struct os_mbuf **rxom); 260 int ble_att_clt_tx_mtu(uint16_t conn_handle, uint16_t mtu); 261 int ble_att_clt_rx_mtu(uint16_t conn_handle, struct os_mbuf **rxom); 262 int ble_att_clt_tx_read(uint16_t conn_handle, uint16_t handle); 263 int ble_att_clt_rx_read(uint16_t conn_handle, struct os_mbuf **rxom); 264 int ble_att_clt_tx_read_blob(uint16_t conn_handle, uint16_t handle, 265 uint16_t offset); 266 int ble_att_clt_rx_read_blob(uint16_t conn_handle, struct os_mbuf **rxom); 267 int ble_att_clt_tx_read_mult(uint16_t conn_handle, 268 const uint16_t *handles, int num_handles); 269 int ble_att_clt_rx_read_mult(uint16_t conn_handle, struct os_mbuf **rxom); 270 int ble_att_clt_tx_read_type(uint16_t conn_handle, uint16_t start_handle, 271 uint16_t end_handle, const ble_uuid_t *uuid); 272 int ble_att_clt_rx_read_type(uint16_t conn_handle, struct os_mbuf **rxom); 273 int ble_att_clt_tx_read_group_type(uint16_t conn_handle, 274 uint16_t start_handle, uint16_t end_handle, 275 const ble_uuid_t *uuid128); 276 int ble_att_clt_rx_read_group_type(uint16_t conn_handle, 277 struct os_mbuf **rxom); 278 int ble_att_clt_tx_find_info(uint16_t conn_handle, uint16_t start_handle, 279 uint16_t end_handle); 280 int ble_att_clt_rx_find_info(uint16_t conn_handle, struct os_mbuf **rxom); 281 int ble_att_clt_tx_find_type_value(uint16_t conn_handle, uint16_t start_handle, 282 uint16_t end_handle, uint16_t attribute_type, 283 const void *attribute_value, int value_len); 284 int ble_att_clt_rx_find_type_value(uint16_t conn_handle, 285 struct os_mbuf **rxom); 286 int ble_att_clt_tx_write_req(uint16_t conn_handle, uint16_t handle, 287 struct os_mbuf *txom); 288 int ble_att_clt_tx_write_cmd(uint16_t conn_handle, uint16_t handle, 289 struct os_mbuf *txom); 290 int ble_att_clt_tx_prep_write(uint16_t conn_handle, uint16_t handle, 291 uint16_t offset, struct os_mbuf *txom); 292 int ble_att_clt_rx_prep_write(uint16_t conn_handle, struct os_mbuf **rxom); 293 int ble_att_clt_tx_exec_write(uint16_t conn_handle, uint8_t flags); 294 int ble_att_clt_rx_exec_write(uint16_t conn_handle, struct os_mbuf **rxom); 295 int ble_att_clt_rx_write(uint16_t conn_handle, struct os_mbuf **rxom); 296 int ble_att_clt_tx_notify(uint16_t conn_handle, uint16_t handle, 297 struct os_mbuf *txom); 298 int ble_att_clt_tx_indicate(uint16_t conn_handle, uint16_t handle, 299 struct os_mbuf *txom); 300 int ble_att_clt_rx_indicate(uint16_t conn_handle, struct os_mbuf **rxom); 301 302 #ifdef __cplusplus 303 } 304 #endif 305 306 #endif 307