1 /** @file 2 * @brief Internal APIs for Bluetooth L2CAP handling. 3 */ 4 5 /* 6 * Copyright (c) 2015-2016 Intel Corporation 7 * 8 * SPDX-License-Identifier: Apache-2.0 9 */ 10 #include <stdbool.h> 11 #include <stddef.h> 12 #include <stdint.h> 13 14 #include <zephyr/bluetooth/conn.h> 15 #include <zephyr/bluetooth/l2cap.h> 16 #include <zephyr/kernel.h> 17 #include <zephyr/net_buf.h> 18 #include <zephyr/sys/iterable_sections.h> 19 #include <zephyr/sys_clock.h> 20 21 #include "host/classic/l2cap_br_interface.h" 22 /* TODO: we should include conn_internal.h for bt_conn_tx_cb_t but that causes redefinitions */ 23 24 enum l2cap_conn_list_action { 25 BT_L2CAP_CHAN_LOOKUP, 26 BT_L2CAP_CHAN_DETACH, 27 }; 28 29 #define BT_L2CAP_CID_BR_SIG 0x0001 30 #define BT_L2CAP_CID_ATT 0x0004 31 #define BT_L2CAP_CID_LE_SIG 0x0005 32 #define BT_L2CAP_CID_SMP 0x0006 33 #define BT_L2CAP_CID_BR_SMP 0x0007 34 35 #define BT_L2CAP_PSM_RFCOMM 0x0003 36 37 struct bt_l2cap_hdr { 38 uint16_t len; 39 uint16_t cid; 40 } __packed; 41 42 struct bt_l2cap_sig_hdr { 43 uint8_t code; 44 uint8_t ident; 45 uint16_t len; 46 } __packed; 47 48 #define BT_L2CAP_REJ_NOT_UNDERSTOOD 0x0000 49 #define BT_L2CAP_REJ_MTU_EXCEEDED 0x0001 50 #define BT_L2CAP_REJ_INVALID_CID 0x0002 51 52 #define BT_L2CAP_CMD_REJECT 0x01 53 struct bt_l2cap_cmd_reject { 54 uint16_t reason; 55 uint8_t data[]; 56 } __packed; 57 58 struct bt_l2cap_cmd_reject_cid_data { 59 uint16_t scid; 60 uint16_t dcid; 61 } __packed; 62 63 #define BT_L2CAP_DISCONN_REQ 0x06 64 struct bt_l2cap_disconn_req { 65 uint16_t dcid; 66 uint16_t scid; 67 } __packed; 68 69 #define BT_L2CAP_DISCONN_RSP 0x07 70 struct bt_l2cap_disconn_rsp { 71 uint16_t dcid; 72 uint16_t scid; 73 } __packed; 74 75 #define BT_L2CAP_CONN_PARAM_REQ 0x12 76 struct bt_l2cap_conn_param_req { 77 uint16_t min_interval; 78 uint16_t max_interval; 79 uint16_t latency; 80 uint16_t timeout; 81 } __packed; 82 83 #define BT_L2CAP_CONN_PARAM_ACCEPTED 0x0000 84 #define BT_L2CAP_CONN_PARAM_REJECTED 0x0001 85 86 #define BT_L2CAP_CONN_PARAM_RSP 0x13 87 struct bt_l2cap_conn_param_rsp { 88 uint16_t result; 89 } __packed; 90 91 #define BT_L2CAP_LE_CONN_REQ 0x14 92 struct bt_l2cap_le_conn_req { 93 uint16_t psm; 94 uint16_t scid; 95 uint16_t mtu; 96 uint16_t mps; 97 uint16_t credits; 98 } __packed; 99 100 /* valid results in conn response on LE */ 101 #define BT_L2CAP_LE_SUCCESS 0x0000 102 #define BT_L2CAP_LE_ERR_PSM_NOT_SUPP 0x0002 103 #define BT_L2CAP_LE_ERR_NO_RESOURCES 0x0004 104 #define BT_L2CAP_LE_ERR_AUTHENTICATION 0x0005 105 #define BT_L2CAP_LE_ERR_AUTHORIZATION 0x0006 106 #define BT_L2CAP_LE_ERR_KEY_SIZE 0x0007 107 #define BT_L2CAP_LE_ERR_ENCRYPTION 0x0008 108 #define BT_L2CAP_LE_ERR_INVALID_SCID 0x0009 109 #define BT_L2CAP_LE_ERR_SCID_IN_USE 0x000A 110 #define BT_L2CAP_LE_ERR_UNACCEPT_PARAMS 0x000B 111 #define BT_L2CAP_LE_ERR_INVALID_PARAMS 0x000C 112 113 #define BT_L2CAP_LE_CONN_RSP 0x15 114 struct bt_l2cap_le_conn_rsp { 115 uint16_t dcid; 116 uint16_t mtu; 117 uint16_t mps; 118 uint16_t credits; 119 uint16_t result; 120 } __packed; 121 122 #define BT_L2CAP_LE_CREDITS 0x16 123 struct bt_l2cap_le_credits { 124 uint16_t cid; 125 uint16_t credits; 126 } __packed; 127 128 #define BT_L2CAP_ECRED_CREDITS_MIN 1 129 #define BT_L2CAP_ECRED_CREDITS_MAX UINT16_MAX 130 131 #define BT_L2CAP_ECRED_CONN_REQ 0x17 132 struct bt_l2cap_ecred_conn_req { 133 uint16_t psm; 134 uint16_t mtu; 135 uint16_t mps; 136 uint16_t credits; 137 uint16_t scid[]; 138 } __packed; 139 140 #define BT_L2CAP_ECRED_CONN_RSP 0x18 141 struct bt_l2cap_ecred_conn_rsp { 142 uint16_t mtu; 143 uint16_t mps; 144 uint16_t credits; 145 uint16_t result; 146 uint16_t dcid[]; 147 } __packed; 148 149 #define BT_L2CAP_ECRED_RECONF_REQ 0x19 150 struct bt_l2cap_ecred_reconf_req { 151 uint16_t mtu; 152 uint16_t mps; 153 uint16_t scid[]; 154 } __packed; 155 156 #define BT_L2CAP_RECONF_SUCCESS 0x0000 157 #define BT_L2CAP_RECONF_INVALID_MTU 0x0001 158 #define BT_L2CAP_RECONF_INVALID_MPS 0x0002 159 #define BT_L2CAP_RECONF_INVALID_CID 0x0003 160 #define BT_L2CAP_RECONF_OTHER_UNACCEPT 0x0004 161 162 #define BT_L2CAP_ECRED_RECONF_RSP 0x1a 163 struct bt_l2cap_ecred_reconf_rsp { 164 uint16_t result; 165 } __packed; 166 167 struct bt_l2cap_fixed_chan { 168 uint16_t cid; 169 int (*accept)(struct bt_conn *conn, struct bt_l2cap_chan **chan); 170 bt_l2cap_chan_destroy_t destroy; 171 }; 172 173 #define BT_L2CAP_CHANNEL_DEFINE(_name, _cid, _accept, _destroy) \ 174 const STRUCT_SECTION_ITERABLE(bt_l2cap_fixed_chan, _name) = { \ 175 .cid = _cid, \ 176 .accept = _accept, \ 177 .destroy = _destroy, \ 178 } 179 180 /* Notify L2CAP channels of a new connection */ 181 void bt_l2cap_connected(struct bt_conn *conn); 182 183 /* Notify L2CAP channels of a disconnect event */ 184 void bt_l2cap_disconnected(struct bt_conn *conn); 185 186 /* Add channel to the connection */ 187 void bt_l2cap_chan_add(struct bt_conn *conn, struct bt_l2cap_chan *chan, 188 bt_l2cap_chan_destroy_t destroy); 189 190 /* Remove channel from the connection */ 191 void bt_l2cap_chan_remove(struct bt_conn *conn, struct bt_l2cap_chan *chan); 192 193 /* Delete channel */ 194 void bt_l2cap_chan_del(struct bt_l2cap_chan *chan); 195 196 const char *bt_l2cap_chan_state_str(bt_l2cap_chan_state_t state); 197 198 #if defined(CONFIG_BT_L2CAP_LOG_LEVEL_DBG) 199 void bt_l2cap_chan_set_state_debug(struct bt_l2cap_chan *chan, 200 bt_l2cap_chan_state_t state, 201 const char *func, int line); 202 #define bt_l2cap_chan_set_state(_chan, _state) \ 203 bt_l2cap_chan_set_state_debug(_chan, _state, __func__, __LINE__) 204 #else 205 void bt_l2cap_chan_set_state(struct bt_l2cap_chan *chan, 206 bt_l2cap_chan_state_t state); 207 #endif /* CONFIG_BT_L2CAP_LOG_LEVEL_DBG */ 208 209 /* 210 * Notify L2CAP channels of a change in encryption state passing additionally 211 * HCI status of performed security procedure. 212 */ 213 void bt_l2cap_security_changed(struct bt_conn *conn, uint8_t hci_status); 214 215 /* Prepare an L2CAP PDU to be sent over a connection */ 216 struct net_buf *bt_l2cap_create_pdu_timeout(struct net_buf_pool *pool, 217 size_t reserve, 218 k_timeout_t timeout); 219 220 #define bt_l2cap_create_pdu(_pool, _reserve) \ 221 bt_l2cap_create_pdu_timeout(_pool, _reserve, K_FOREVER) 222 223 /* Send L2CAP PDU over a connection 224 * 225 * Buffer ownership is transferred to stack in case of success. 226 */ 227 int bt_l2cap_send_pdu(struct bt_l2cap_le_chan *le_chan, struct net_buf *pdu, 228 bt_conn_tx_cb_t cb, void *user_data); 229 230 /* Receive a new L2CAP PDU from a connection */ 231 void bt_l2cap_recv(struct bt_conn *conn, struct net_buf *buf, bool complete); 232 233 /* Perform connection parameter update request */ 234 int bt_l2cap_update_conn_param(struct bt_conn *conn, 235 const struct bt_le_conn_param *param); 236 237 /* Initialize L2CAP and supported channels */ 238 void bt_l2cap_init(void); 239 240 /* Lookup channel by Transmission CID */ 241 struct bt_l2cap_chan *bt_l2cap_le_lookup_tx_cid(struct bt_conn *conn, 242 uint16_t cid); 243 244 /* Lookup channel by Receiver CID */ 245 struct bt_l2cap_chan *bt_l2cap_le_lookup_rx_cid(struct bt_conn *conn, 246 uint16_t cid); 247 248 struct bt_l2cap_ecred_cb { 249 void (*ecred_conn_rsp)(struct bt_conn *conn, uint16_t result, uint8_t attempted, 250 uint8_t succeeded, uint16_t psm); 251 void (*ecred_conn_req)(struct bt_conn *conn, uint16_t result, uint16_t psm); 252 }; 253 254 /* Register callbacks for Enhanced Credit based Flow Control */ 255 void bt_l2cap_register_ecred_cb(const struct bt_l2cap_ecred_cb *cb); 256 257 /* Returns a server if it exists for given psm. */ 258 struct bt_l2cap_server *bt_l2cap_server_lookup_psm(uint16_t psm); 259 260 /* Pull data from the L2CAP layer */ 261 struct net_buf *l2cap_data_pull(struct bt_conn *conn, 262 size_t amount, 263 size_t *length); 264