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