Lines Matching +full:conf +full:- +full:tx
1 /* l2cap_br.c - L2CAP BREDR oriented handling */
6 * SPDX-License-Identifier: Apache-2.0
107 SYS_SLIST_FOR_EACH_CONTAINER(&conn->channels, chan, node) { in bt_l2cap_br_lookup_rx_cid()
108 if (BR_CHAN(chan)->rx.cid == cid) { in bt_l2cap_br_lookup_rx_cid()
121 SYS_SLIST_FOR_EACH_CONTAINER(&conn->channels, chan, node) { in bt_l2cap_br_lookup_tx_cid()
122 if (BR_CHAN(chan)->tx.cid == cid) { in bt_l2cap_br_lookup_tx_cid()
142 return br_chan_sig->info_fixed_chan; in bt_l2cap_br_get_remote_fixed_chan()
155 if (br_chan->rx.cid > 0) { in l2cap_br_chan_alloc_cid()
165 br_chan->rx.cid = cid; in l2cap_br_chan_alloc_cid()
175 bt_l2cap_chan_remove(chan->conn, chan); in l2cap_br_chan_cleanup()
183 LOG_DBG("chan %p cid 0x%04x", br_chan, br_chan->rx.cid); in l2cap_br_chan_destroy()
185 /* Cancel ongoing work. Since the channel can be re-used after this in l2cap_br_chan_destroy()
192 struct k_work_q *rtx_work_queue = br_chan->rtx_work.queue; in l2cap_br_chan_destroy()
194 if (rtx_work_queue == NULL || k_current_get() != &rtx_work_queue->thread) { in l2cap_br_chan_destroy()
195 k_work_cancel_delayable_sync(&br_chan->rtx_work, &br_chan->rtx_sync); in l2cap_br_chan_destroy()
197 k_work_cancel_delayable(&br_chan->rtx_work); in l2cap_br_chan_destroy()
200 atomic_clear(BR_CHAN(chan)->flags); in l2cap_br_chan_destroy()
209 if (chan->rx.cid == BT_L2CAP_CID_BR_SIG) { in l2cap_br_rtx_timeout()
211 atomic_clear_bit(chan->flags, L2CAP_FLAG_SIG_INFO_PENDING); in l2cap_br_rtx_timeout()
215 LOG_DBG("chan %p %s scid 0x%04x", chan, bt_l2cap_chan_state_str(chan->state), chan->rx.cid); in l2cap_br_rtx_timeout()
217 switch (chan->state) { in l2cap_br_rtx_timeout()
219 bt_l2cap_br_chan_disconnect(&chan->chan); in l2cap_br_rtx_timeout()
223 l2cap_br_chan_cleanup(&chan->chan); in l2cap_br_rtx_timeout()
240 k_fifo_init(&ch->_pdu_tx_queue); in l2cap_br_chan_add()
248 k_work_init_delayable(&ch->rtx_work, l2cap_br_rtx_timeout); in l2cap_br_chan_add()
269 if (!atomic_set(&br_chan->_pdu_ready_lock, 1)) { in raise_data_ready()
270 sys_slist_append(&br_chan->chan.conn->l2cap_data_ready, in raise_data_ready()
271 &br_chan->_pdu_ready); in raise_data_ready()
277 bt_conn_data_ready(br_chan->chan.conn); in raise_data_ready()
282 struct bt_conn *conn = br_chan->chan.conn; in lower_data_ready()
283 __maybe_unused sys_snode_t *s = sys_slist_get(&conn->l2cap_data_ready); in lower_data_ready()
285 __ASSERT_NO_MSG(s == &br_chan->_pdu_ready); in lower_data_ready()
287 __maybe_unused atomic_t old = atomic_set(&br_chan->_pdu_ready_lock, 0); in lower_data_ready()
294 struct bt_conn *conn = br_chan->chan.conn; in cancel_data_ready()
296 sys_slist_find_and_remove(&conn->l2cap_data_ready, in cancel_data_ready()
297 &br_chan->_pdu_ready); in cancel_data_ready()
299 atomic_set(&br_chan->_pdu_ready_lock, 0); in cancel_data_ready()
309 LOG_DBG("chan %p buf %p len %zu", br_chan, buf, buf->len); in bt_l2cap_br_send_cb()
312 hdr->len = sys_cpu_to_le16(buf->len - sizeof(*hdr)); in bt_l2cap_br_send_cb()
313 hdr->cid = sys_cpu_to_le16(cid); in bt_l2cap_br_send_cb()
315 if (buf->user_data_size < sizeof(struct closure)) { in bt_l2cap_br_send_cb()
317 buf->user_data_size, in bt_l2cap_br_send_cb()
319 buf->pool_id); in bt_l2cap_br_send_cb()
320 return -EINVAL; in bt_l2cap_br_send_cb()
325 make_closure(buf->user_data, cb, user_data); in bt_l2cap_br_send_cb()
326 k_fifo_put(&br_chan->_pdu_tx_queue, buf); in bt_l2cap_br_send_cb()
348 if (bt_l2cap_br_send_cb(chan->chan.conn, BT_L2CAP_CID_BR_SIG, buf, in l2cap_br_chan_send_req()
356 * The value of this timer is implementation-dependent but the minimum in l2cap_br_chan_send_req()
363 k_work_reschedule(&chan->rtx_work, timeout); in l2cap_br_chan_send_req()
369 return !k_fifo_is_empty(&br_chan->_pdu_tx_queue); in chan_has_data()
376 const sys_snode_t *pdu_ready = sys_slist_peek_head(&conn->l2cap_data_ready); in l2cap_br_data_pull()
390 struct net_buf *pdu = k_fifo_peek_head(&br_chan->_pdu_tx_queue); in l2cap_br_data_pull()
392 __ASSERT(pdu, "signaled ready but no PDUs in the TX queue"); in l2cap_br_data_pull()
400 * same ACL conn -> we have to wait until a full L2 PDU is transferred in l2cap_br_data_pull()
403 bool last_frag = amount >= pdu->len; in l2cap_br_data_pull()
407 __maybe_unused struct net_buf *b = k_fifo_get(&br_chan->_pdu_tx_queue, K_NO_WAIT); in l2cap_br_data_pull()
421 *length = pdu->len; in l2cap_br_data_pull()
434 if (atomic_test_bit(l2cap->chan.flags, L2CAP_FLAG_SIG_INFO_PENDING)) { in l2cap_br_get_info()
449 atomic_set_bit(l2cap->chan.flags, L2CAP_FLAG_SIG_INFO_PENDING); in l2cap_br_get_info()
450 l2cap->info_ident = l2cap_br_get_ident(); in l2cap_br_get_info()
453 hdr->code = BT_L2CAP_INFO_REQ; in l2cap_br_get_info()
454 hdr->ident = l2cap->info_ident; in l2cap_br_get_info()
455 hdr->len = sys_cpu_to_le16(sizeof(*info)); in l2cap_br_get_info()
458 info->type = sys_cpu_to_le16(info_type); in l2cap_br_get_info()
460 l2cap_br_chan_send_req(&l2cap->chan, buf, L2CAP_BR_INFO_TIMEOUT); in l2cap_br_get_info()
465 if (atomic_test_and_set_bit(chan->flags, L2CAP_FLAG_FIXED_CONNECTED)) { in connect_fixed_channel()
469 if (chan->chan.ops && chan->chan.ops->connected) { in connect_fixed_channel()
470 chan->chan.ops->connected(&chan->chan); in connect_fixed_channel()
477 if (l2cap->info_fixed_chan & BIT(BT_L2CAP_CID_BR_SMP)) { in connect_optional_fixed_channels()
480 chan = bt_l2cap_br_lookup_rx_cid(l2cap->chan.chan.conn, in connect_optional_fixed_channels()
495 if (atomic_test_bit(l2cap->chan.flags, L2CAP_FLAG_SIG_INFO_DONE)) { in l2cap_br_info_rsp()
499 if (atomic_test_and_clear_bit(l2cap->chan.flags, in l2cap_br_info_rsp()
505 k_work_cancel_delayable(&l2cap->chan.rtx_work); in l2cap_br_info_rsp()
508 if (buf->len < sizeof(*rsp)) { in l2cap_br_info_rsp()
510 err = -EINVAL; in l2cap_br_info_rsp()
514 if (ident != l2cap->info_ident) { in l2cap_br_info_rsp()
516 err = -EINVAL; in l2cap_br_info_rsp()
521 result = sys_le16_to_cpu(rsp->result); in l2cap_br_info_rsp()
524 err = -EINVAL; in l2cap_br_info_rsp()
528 type = sys_le16_to_cpu(rsp->type); in l2cap_br_info_rsp()
532 if (buf->len < sizeof(uint32_t)) { in l2cap_br_info_rsp()
534 err = -EINVAL; in l2cap_br_info_rsp()
537 l2cap->info_feat_mask = net_buf_pull_le32(buf); in l2cap_br_info_rsp()
538 LOG_DBG("remote info mask 0x%08x", l2cap->info_feat_mask); in l2cap_br_info_rsp()
540 if (!(l2cap->info_feat_mask & L2CAP_FEAT_FIXED_CHAN_MASK)) { in l2cap_br_info_rsp()
547 if (buf->len < sizeof(uint8_t)) { in l2cap_br_info_rsp()
549 err = -EINVAL; in l2cap_br_info_rsp()
560 l2cap->info_fixed_chan = net_buf_pull_u8(buf); in l2cap_br_info_rsp()
561 LOG_DBG("remote fixed channel mask 0x%02x", l2cap->info_fixed_chan); in l2cap_br_info_rsp()
568 err = -EINVAL; in l2cap_br_info_rsp()
572 atomic_set_bit(l2cap->chan.flags, L2CAP_FLAG_SIG_INFO_DONE); in l2cap_br_info_rsp()
573 l2cap->info_ident = 0U; in l2cap_br_info_rsp()
583 mask |= BIT(fchan->cid); in get_fixed_channels_mask()
592 struct bt_conn *conn = l2cap->chan.chan.conn; in l2cap_br_info_req()
593 struct bt_l2cap_info_req *req = (void *)buf->data; in l2cap_br_info_req()
599 if (buf->len < sizeof(*req)) { in l2cap_br_info_req()
601 return -EINVAL; in l2cap_br_info_req()
606 type = sys_le16_to_cpu(req->type); in l2cap_br_info_req()
610 hdr_info->code = BT_L2CAP_INFO_RSP; in l2cap_br_info_req()
611 hdr_info->ident = ident; in l2cap_br_info_req()
617 rsp->type = sys_cpu_to_le16(BT_L2CAP_INFO_FEAT_MASK); in l2cap_br_info_req()
618 rsp->result = sys_cpu_to_le16(BT_L2CAP_INFO_SUCCESS); in l2cap_br_info_req()
620 hdr_info->len = sys_cpu_to_le16(sizeof(*rsp) + sizeof(uint32_t)); in l2cap_br_info_req()
623 rsp->type = sys_cpu_to_le16(BT_L2CAP_INFO_FIXED_CHAN); in l2cap_br_info_req()
624 rsp->result = sys_cpu_to_le16(BT_L2CAP_INFO_SUCCESS); in l2cap_br_info_req()
627 rsp->data[0] = get_fixed_channels_mask(); in l2cap_br_info_req()
629 hdr_info->len = sys_cpu_to_le16(sizeof(*rsp) + 8); in l2cap_br_info_req()
632 rsp->type = req->type; in l2cap_br_info_req()
633 rsp->result = sys_cpu_to_le16(BT_L2CAP_INFO_NOTSUPP); in l2cap_br_info_req()
634 hdr_info->len = sys_cpu_to_le16(sizeof(*rsp)); in l2cap_br_info_req()
650 if (!fchan->accept) { in bt_l2cap_br_connected()
654 if (fchan->accept(conn, &chan) < 0) { in bt_l2cap_br_connected()
660 br_chan->rx.cid = fchan->cid; in bt_l2cap_br_connected()
661 br_chan->tx.cid = fchan->cid; in bt_l2cap_br_connected()
671 if (fchan->cid == BT_L2CAP_CID_BR_SIG) { in bt_l2cap_br_connected()
686 SYS_SLIST_FOR_EACH_CONTAINER_SAFE(&conn->channels, chan, next, node) { in bt_l2cap_br_disconnected()
696 if (server->psm == psm) { in l2cap_br_server_lookup_psm()
713 net_buf_add_u8(buf, opt->type & BT_L2CAP_CONF_MASK); in l2cap_br_conf_add_opt()
714 net_buf_add_u8(buf, opt->len); in l2cap_br_conf_add_opt()
715 net_buf_add_mem(buf, opt->data, opt->len); in l2cap_br_conf_add_opt()
721 struct bt_l2cap_conf_req *conf; in l2cap_br_conf() local
727 hdr->code = BT_L2CAP_CONF_REQ; in l2cap_br_conf()
728 hdr->ident = l2cap_br_get_ident(); in l2cap_br_conf()
729 conf = net_buf_add(buf, sizeof(*conf)); in l2cap_br_conf()
730 (void)memset(conf, 0, sizeof(*conf)); in l2cap_br_conf()
732 conf->dcid = sys_cpu_to_le16(BR_CHAN(chan)->tx.cid); in l2cap_br_conf()
738 if (BR_CHAN(chan)->rx.mtu != L2CAP_BR_DEFAULT_MTU) { in l2cap_br_conf()
739 l2cap_br_conf_add_mtu(buf, BR_CHAN(chan)->rx.mtu); in l2cap_br_conf()
742 hdr->len = sys_cpu_to_le16(buf->len - sizeof(*hdr)); in l2cap_br_conf()
761 * - existing security on link is applicable for requested PSM in connection,
762 * - legacy (non SSP) devices connecting with low security requirements,
764 * - channel connection process is on hold since there were valid security
767 * - bt_conn_set_security API returns < 0.
777 if (br_chan->required_sec_level == BT_SECURITY_L0) { in l2cap_br_conn_security()
785 if (br_chan->required_sec_level == BT_SECURITY_L1 && in l2cap_br_conn_security()
786 !BT_FEAT_HOST_SSP(chan->conn->br.features)) { in l2cap_br_conn_security()
790 switch (br_chan->required_sec_level) { in l2cap_br_conn_security()
802 if (BT_FEAT_HOST_SSP(chan->conn->br.features)) { in l2cap_br_conn_security()
803 br_chan->required_sec_level = BT_SECURITY_L2; in l2cap_br_conn_security()
808 check = bt_conn_set_security(chan->conn, br_chan->required_sec_level); in l2cap_br_conn_security()
817 chan->conn->sec_level >= br_chan->required_sec_level) { in l2cap_br_conn_security()
833 atomic_set_bit(chan->conn->flags, BT_CONN_BR_GENERAL_BONDING); in l2cap_br_conn_security()
855 hdr->code = BT_L2CAP_CONN_RSP; in l2cap_br_send_conn_rsp()
856 hdr->ident = ident; in l2cap_br_send_conn_rsp()
857 hdr->len = sys_cpu_to_le16(sizeof(*rsp)); in l2cap_br_send_conn_rsp()
860 rsp->dcid = sys_cpu_to_le16(dcid); in l2cap_br_send_conn_rsp()
861 rsp->scid = sys_cpu_to_le16(scid); in l2cap_br_send_conn_rsp()
862 rsp->result = sys_cpu_to_le16(result); in l2cap_br_send_conn_rsp()
865 rsp->status = sys_cpu_to_le16(BT_L2CAP_CS_AUTHEN_PEND); in l2cap_br_send_conn_rsp()
867 rsp->status = sys_cpu_to_le16(BT_L2CAP_CS_NO_INFO); in l2cap_br_send_conn_rsp()
876 if (!atomic_test_bit(BR_CHAN(chan)->flags, L2CAP_FLAG_CONN_ACCEPTOR)) { in l2cap_br_conn_req_reply()
877 return -ESRCH; in l2cap_br_conn_req_reply()
880 l2cap_br_send_conn_rsp(chan->conn, BR_CHAN(chan)->tx.cid, in l2cap_br_conn_req_reply()
881 BR_CHAN(chan)->rx.cid, BR_CHAN(chan)->ident, result); in l2cap_br_conn_req_reply()
882 BR_CHAN(chan)->ident = 0U; in l2cap_br_conn_req_reply()
897 LOG_DBG("chan %p psm 0x%04x %s -> %s", chan, br_chan->psm, in bt_l2cap_br_chan_set_state_debug()
898 bt_l2cap_chan_state_str(br_chan->state), bt_l2cap_chan_state_str(state)); in bt_l2cap_br_chan_set_state_debug()
906 if (br_chan->state != BT_L2CAP_DISCONNECTED) { in bt_l2cap_br_chan_set_state_debug()
911 if (br_chan->state != BT_L2CAP_CONNECTING) { in bt_l2cap_br_chan_set_state_debug()
916 if (br_chan->state != BT_L2CAP_CONFIG && in bt_l2cap_br_chan_set_state_debug()
917 br_chan->state != BT_L2CAP_CONNECTING) { in bt_l2cap_br_chan_set_state_debug()
922 if (br_chan->state != BT_L2CAP_CONFIG && in bt_l2cap_br_chan_set_state_debug()
923 br_chan->state != BT_L2CAP_CONNECTED) { in bt_l2cap_br_chan_set_state_debug()
932 br_chan->state = state; in bt_l2cap_br_chan_set_state_debug()
938 BR_CHAN(chan)->state = state; in bt_l2cap_br_chan_set_state()
945 const struct bt_l2cap_chan_ops *ops = chan->ops; in bt_l2cap_br_chan_del()
948 LOG_DBG("conn %p chan %p", chan->conn, chan); in bt_l2cap_br_chan_del()
950 if (!chan->conn) { in bt_l2cap_br_chan_del()
956 /* Remove buffers on the PDU TX queue. */ in bt_l2cap_br_chan_del()
958 struct net_buf *buf = k_fifo_get(&br_chan->_pdu_tx_queue, K_NO_WAIT); in bt_l2cap_br_chan_del()
963 if (ops->disconnected) { in bt_l2cap_br_chan_del()
964 ops->disconnected(chan); in bt_l2cap_br_chan_del()
967 chan->conn = NULL; in bt_l2cap_br_chan_del()
973 BR_CHAN(chan)->psm = 0U; in bt_l2cap_br_chan_del()
975 if (chan->destroy) { in bt_l2cap_br_chan_del()
976 chan->destroy(chan); in bt_l2cap_br_chan_del()
979 if (ops->released) { in bt_l2cap_br_chan_del()
980 ops->released(chan); in bt_l2cap_br_chan_del()
987 struct bt_conn *conn = l2cap->chan.chan.conn; in l2cap_br_conn_req()
990 struct bt_l2cap_conn_req *req = (void *)buf->data; in l2cap_br_conn_req()
994 if (buf->len < sizeof(*req)) { in l2cap_br_conn_req()
999 psm = sys_le16_to_cpu(req->psm); in l2cap_br_conn_req()
1000 scid = sys_le16_to_cpu(req->scid); in l2cap_br_conn_req()
1015 if (server->sec_level != BT_SECURITY_L0 && in l2cap_br_conn_req()
1016 BT_FEAT_HOST_SSP(conn->br.features) && !conn->encrypt) { in l2cap_br_conn_req()
1042 if (server->accept(conn, server, &chan) < 0) { in l2cap_br_conn_req()
1048 br_chan->required_sec_level = server->sec_level; in l2cap_br_conn_req()
1051 BR_CHAN(chan)->tx.cid = scid; in l2cap_br_conn_req()
1052 br_chan->ident = ident; in l2cap_br_conn_req()
1054 atomic_set_bit(BR_CHAN(chan)->flags, L2CAP_FLAG_CONN_ACCEPTOR); in l2cap_br_conn_req()
1057 BR_CHAN(chan)->rx.mtu = MIN(BR_CHAN(chan)->rx.mtu, BT_L2CAP_RX_MTU); in l2cap_br_conn_req()
1081 br_chan->ident = ident; in l2cap_br_conn_req()
1098 struct bt_conn *conn = l2cap->chan.chan.conn; in l2cap_br_conf_rsp()
1100 struct bt_l2cap_conf_rsp *rsp = (void *)buf->data; in l2cap_br_conf_rsp()
1104 if (buf->len < sizeof(*rsp)) { in l2cap_br_conf_rsp()
1105 LOG_ERR("Too small L2CAP conf rsp packet size"); in l2cap_br_conf_rsp()
1109 flags = sys_le16_to_cpu(rsp->flags); in l2cap_br_conf_rsp()
1110 scid = sys_le16_to_cpu(rsp->scid); in l2cap_br_conf_rsp()
1111 result = sys_le16_to_cpu(rsp->result); in l2cap_br_conf_rsp()
1112 opt_len = len - sizeof(*rsp); in l2cap_br_conf_rsp()
1125 k_work_cancel_delayable(&br_chan->rtx_work); in l2cap_br_conf_rsp()
1133 atomic_set_bit(br_chan->flags, L2CAP_FLAG_CONN_LCONF_DONE); in l2cap_br_conf_rsp()
1135 if (br_chan->state == BT_L2CAP_CONFIG && in l2cap_br_conf_rsp()
1136 atomic_test_bit(br_chan->flags, in l2cap_br_conf_rsp()
1138 LOG_DBG("scid 0x%04x rx MTU %u dcid 0x%04x tx MTU %u", br_chan->rx.cid, in l2cap_br_conf_rsp()
1139 br_chan->rx.mtu, br_chan->tx.cid, br_chan->tx.mtu); in l2cap_br_conf_rsp()
1142 if (chan->ops && chan->ops->connected) { in l2cap_br_conf_rsp()
1143 chan->ops->connected(chan); in l2cap_br_conf_rsp()
1156 if (server->psm < L2CAP_BR_PSM_START || !server->accept) { in bt_l2cap_br_server_register()
1157 return -EINVAL; in bt_l2cap_br_server_register()
1161 if ((server->psm & 0x0101) != 0x0001) { in bt_l2cap_br_server_register()
1162 return -EINVAL; in bt_l2cap_br_server_register()
1165 if (server->sec_level > BT_SECURITY_L4) { in bt_l2cap_br_server_register()
1166 return -EINVAL; in bt_l2cap_br_server_register()
1167 } else if (server->sec_level == BT_SECURITY_L0 && in bt_l2cap_br_server_register()
1168 server->psm != L2CAP_BR_PSM_SDP) { in bt_l2cap_br_server_register()
1169 server->sec_level = BT_SECURITY_L1; in bt_l2cap_br_server_register()
1173 if (l2cap_br_server_lookup_psm(server->psm)) { in bt_l2cap_br_server_register()
1175 return -EADDRINUSE; in bt_l2cap_br_server_register()
1178 LOG_DBG("PSM 0x%04x", server->psm); in bt_l2cap_br_server_register()
1180 sys_slist_append(&br_servers, &server->node); in bt_l2cap_br_server_register()
1195 hdr->code = BT_L2CAP_CMD_REJECT; in l2cap_br_send_reject()
1196 hdr->ident = ident; in l2cap_br_send_reject()
1197 hdr->len = sys_cpu_to_le16(sizeof(*rej) + data_len); in l2cap_br_send_reject()
1200 rej->reason = sys_cpu_to_le16(reason); in l2cap_br_send_reject()
1203 * optional data if available must be already in little-endian format in l2cap_br_send_reject()
1222 LOG_ERR("tx MTU length %zu invalid", len); in l2cap_br_conf_opt_mtu()
1227 opt_mtu = (struct bt_l2cap_conf_opt_mtu *)buf->data; in l2cap_br_conf_opt_mtu()
1229 mtu = sys_le16_to_cpu(opt_mtu->mtu); in l2cap_br_conf_opt_mtu()
1232 BR_CHAN(chan)->tx.mtu = L2CAP_BR_MIN_MTU; in l2cap_br_conf_opt_mtu()
1233 opt_mtu->mtu = sys_cpu_to_le16(L2CAP_BR_MIN_MTU); in l2cap_br_conf_opt_mtu()
1234 LOG_DBG("tx MTU %u invalid", mtu); in l2cap_br_conf_opt_mtu()
1238 BR_CHAN(chan)->tx.mtu = mtu; in l2cap_br_conf_opt_mtu()
1239 LOG_DBG("tx MTU %u", mtu); in l2cap_br_conf_opt_mtu()
1256 opt_to = (struct bt_l2cap_conf_opt_flush_timeout *)buf->data; in l2cap_br_conf_opt_flush_timeout()
1258 LOG_DBG("Flush timeout %u", opt_to->timeout); in l2cap_br_conf_opt_flush_timeout()
1260 opt_to->timeout = sys_cpu_to_le16(0xFFFF); in l2cap_br_conf_opt_flush_timeout()
1278 opt_qos = (struct bt_l2cap_conf_opt_qos *)buf->data; in l2cap_br_conf_opt_qos()
1280 LOG_DBG("QOS Type %u", opt_qos->service_type); in l2cap_br_conf_opt_qos()
1282 if (opt_qos->service_type == BT_L2CAP_QOS_TYPE_GUARANTEED) { in l2cap_br_conf_opt_qos()
1285 opt_qos->flags = 0x00; in l2cap_br_conf_opt_qos()
1287 opt_qos->token_rate = sys_cpu_to_le32(0x00000000); in l2cap_br_conf_opt_qos()
1289 opt_qos->token_bucket_size = sys_cpu_to_le32(0x00000000); in l2cap_br_conf_opt_qos()
1291 opt_qos->peak_bandwidth = sys_cpu_to_le32(0x00000000); in l2cap_br_conf_opt_qos()
1293 opt_qos->latency = sys_cpu_to_le32(0xFFFFFFFF); in l2cap_br_conf_opt_qos()
1295 opt_qos->delay_variation = sys_cpu_to_le32(0xFFFFFFFF); in l2cap_br_conf_opt_qos()
1314 opt_ret_fc = (struct bt_l2cap_conf_opt_ret_fc *)buf->data; in l2cap_br_conf_opt_ret_fc()
1316 LOG_DBG("ret_fc mode %u", opt_ret_fc->mode); in l2cap_br_conf_opt_ret_fc()
1318 if (opt_ret_fc->mode != BT_L2CAP_RET_FC_MODE_BASIC) { in l2cap_br_conf_opt_ret_fc()
1321 opt_ret_fc->mode = BT_L2CAP_RET_FC_MODE_BASIC; in l2cap_br_conf_opt_ret_fc()
1340 opt_fcs = (struct bt_l2cap_conf_opt_fcs *)buf->data; in l2cap_br_conf_opt_fcs()
1342 LOG_DBG("FCS type %u", opt_fcs->type); in l2cap_br_conf_opt_fcs()
1344 if (opt_fcs->type != BT_L2CAP_FCS_TYPE_NO) { in l2cap_br_conf_opt_fcs()
1347 opt_fcs->type = BT_L2CAP_FCS_TYPE_NO; in l2cap_br_conf_opt_fcs()
1357 struct bt_conn *conn = l2cap->chan.chan.conn; in l2cap_br_conf_req()
1365 if (buf->len < sizeof(*req)) { in l2cap_br_conf_req()
1366 LOG_ERR("Too small L2CAP conf req packet size"); in l2cap_br_conf_req()
1371 flags = sys_le16_to_cpu(req->flags); in l2cap_br_conf_req()
1372 dcid = sys_le16_to_cpu(req->dcid); in l2cap_br_conf_req()
1373 opt_len = len - sizeof(*req); in l2cap_br_conf_req()
1381 .scid = req->dcid, in l2cap_br_conf_req()
1391 LOG_DBG("tx default MTU %u", L2CAP_BR_DEFAULT_MTU); in l2cap_br_conf_req()
1392 BR_CHAN(chan)->tx.mtu = L2CAP_BR_DEFAULT_MTU; in l2cap_br_conf_req()
1396 while (buf->len >= sizeof(*opt)) { in l2cap_br_conf_req()
1400 if (buf->len < opt->len) { in l2cap_br_conf_req()
1406 hint = opt->type & BT_L2CAP_CONF_HINT; in l2cap_br_conf_req()
1408 switch (opt->type & BT_L2CAP_CONF_MASK) { in l2cap_br_conf_req()
1411 result = l2cap_br_conf_opt_mtu(chan, buf, opt->len); in l2cap_br_conf_req()
1420 result = l2cap_br_conf_opt_flush_timeout(chan, buf, opt->len); in l2cap_br_conf_req()
1426 result = l2cap_br_conf_opt_qos(chan, buf, opt->len); in l2cap_br_conf_req()
1432 result = l2cap_br_conf_opt_ret_fc(chan, buf, opt->len); in l2cap_br_conf_req()
1438 result = l2cap_br_conf_opt_fcs(chan, buf, opt->len); in l2cap_br_conf_req()
1450 LOG_DBG("option %u not handled", opt->type); in l2cap_br_conf_req()
1458 net_buf_pull(buf, opt->len); in l2cap_br_conf_req()
1465 hdr->code = BT_L2CAP_CONF_RSP; in l2cap_br_conf_req()
1466 hdr->ident = ident; in l2cap_br_conf_req()
1470 rsp->result = sys_cpu_to_le16(result); in l2cap_br_conf_req()
1471 rsp->scid = sys_cpu_to_le16(BR_CHAN(chan)->tx.cid); in l2cap_br_conf_req()
1481 rsp->flags = sys_cpu_to_le16(flags & BT_L2CAP_CONF_FLAGS_MASK); in l2cap_br_conf_req()
1494 hdr->len = sys_cpu_to_le16(buf->len - sizeof(*hdr)); in l2cap_br_conf_req()
1502 atomic_set_bit(BR_CHAN(chan)->flags, L2CAP_FLAG_CONN_RCONF_DONE); in l2cap_br_conf_req()
1504 if (atomic_test_bit(BR_CHAN(chan)->flags, L2CAP_FLAG_CONN_LCONF_DONE) && in l2cap_br_conf_req()
1505 BR_CHAN(chan)->state == BT_L2CAP_CONFIG) { in l2cap_br_conf_req()
1506 LOG_DBG("scid 0x%04x rx MTU %u dcid 0x%04x tx MTU %u", BR_CHAN(chan)->rx.cid, in l2cap_br_conf_req()
1507 BR_CHAN(chan)->rx.mtu, BR_CHAN(chan)->tx.cid, BR_CHAN(chan)->tx.mtu); in l2cap_br_conf_req()
1510 if (chan->ops && chan->ops->connected) { in l2cap_br_conf_req()
1511 chan->ops->connected(chan); in l2cap_br_conf_req()
1527 SYS_SLIST_FOR_EACH_CONTAINER(&conn->channels, chan, node) { in l2cap_br_remove_tx_cid()
1528 if (BR_CHAN(chan)->tx.cid == cid) { in l2cap_br_remove_tx_cid()
1529 sys_slist_remove(&conn->channels, prev, &chan->node); in l2cap_br_remove_tx_cid()
1533 prev = &chan->node; in l2cap_br_remove_tx_cid()
1542 struct bt_conn *conn = l2cap->chan.chan.conn; in l2cap_br_disconn_req()
1544 struct bt_l2cap_disconn_req *req = (void *)buf->data; in l2cap_br_disconn_req()
1549 if (buf->len < sizeof(*req)) { in l2cap_br_disconn_req()
1554 dcid = sys_le16_to_cpu(req->dcid); in l2cap_br_disconn_req()
1555 scid = sys_le16_to_cpu(req->scid); in l2cap_br_disconn_req()
1563 data.scid = req->scid; in l2cap_br_disconn_req()
1564 data.dcid = req->dcid; in l2cap_br_disconn_req()
1573 hdr->code = BT_L2CAP_DISCONN_RSP; in l2cap_br_disconn_req()
1574 hdr->ident = ident; in l2cap_br_disconn_req()
1575 hdr->len = sys_cpu_to_le16(sizeof(*rsp)); in l2cap_br_disconn_req()
1578 rsp->dcid = sys_cpu_to_le16(chan->rx.cid); in l2cap_br_disconn_req()
1579 rsp->scid = sys_cpu_to_le16(chan->tx.cid); in l2cap_br_disconn_req()
1581 bt_l2cap_br_chan_del(&chan->chan); in l2cap_br_disconn_req()
1588 LOG_DBG("ch %p cid 0x%04x", BR_CHAN(chan), BR_CHAN(chan)->rx.cid); in l2cap_br_connected()
1595 LOG_DBG("ch %p cid 0x%04x", br_chan, br_chan->rx.cid); in l2cap_br_disconnected()
1597 if (atomic_test_and_clear_bit(br_chan->flags, in l2cap_br_disconnected()
1603 (void)k_work_cancel_delayable(&br_chan->rtx_work); in l2cap_br_disconnected()
1609 struct bt_conn *conn = chan->conn; in bt_l2cap_br_chan_disconnect()
1616 return -ENOTCONN; in bt_l2cap_br_chan_disconnect()
1621 if (br_chan->state == BT_L2CAP_DISCONNECTING) { in bt_l2cap_br_chan_disconnect()
1622 return -EALREADY; in bt_l2cap_br_chan_disconnect()
1625 LOG_DBG("chan %p scid 0x%04x dcid 0x%04x", chan, br_chan->rx.cid, br_chan->tx.cid); in bt_l2cap_br_chan_disconnect()
1630 hdr->code = BT_L2CAP_DISCONN_REQ; in bt_l2cap_br_chan_disconnect()
1631 hdr->ident = l2cap_br_get_ident(); in bt_l2cap_br_chan_disconnect()
1632 hdr->len = sys_cpu_to_le16(sizeof(*req)); in bt_l2cap_br_chan_disconnect()
1635 req->dcid = sys_cpu_to_le16(br_chan->tx.cid); in bt_l2cap_br_chan_disconnect()
1636 req->scid = sys_cpu_to_le16(br_chan->rx.cid); in bt_l2cap_br_chan_disconnect()
1647 struct bt_conn *conn = l2cap->chan.chan.conn; in l2cap_br_disconn_rsp()
1649 struct bt_l2cap_disconn_rsp *rsp = (void *)buf->data; in l2cap_br_disconn_rsp()
1652 if (buf->len < sizeof(*rsp)) { in l2cap_br_disconn_rsp()
1657 dcid = sys_le16_to_cpu(rsp->dcid); in l2cap_br_disconn_rsp()
1658 scid = sys_le16_to_cpu(rsp->scid); in l2cap_br_disconn_rsp()
1668 bt_l2cap_br_chan_del(&chan->chan); in l2cap_br_disconn_rsp()
1680 return -EINVAL; in bt_l2cap_br_chan_connect()
1683 if (br_chan->psm) { in bt_l2cap_br_chan_connect()
1684 return -EEXIST; in bt_l2cap_br_chan_connect()
1689 return -EINVAL; in bt_l2cap_br_chan_connect()
1692 if (br_chan->required_sec_level > BT_SECURITY_L4) { in bt_l2cap_br_chan_connect()
1693 return -EINVAL; in bt_l2cap_br_chan_connect()
1694 } else if (br_chan->required_sec_level == BT_SECURITY_L0 && in bt_l2cap_br_chan_connect()
1696 br_chan->required_sec_level = BT_SECURITY_L1; in bt_l2cap_br_chan_connect()
1699 switch (br_chan->state) { in bt_l2cap_br_chan_connect()
1702 return -EISCONN; in bt_l2cap_br_chan_connect()
1710 return -EBUSY; in bt_l2cap_br_chan_connect()
1714 return -ENOMEM; in bt_l2cap_br_chan_connect()
1717 br_chan->psm = psm; in bt_l2cap_br_chan_connect()
1719 atomic_set_bit(BR_CHAN(chan)->flags, L2CAP_FLAG_CONN_PENDING); in bt_l2cap_br_chan_connect()
1733 return -EIO; in bt_l2cap_br_chan_connect()
1739 hdr->code = BT_L2CAP_CONN_REQ; in bt_l2cap_br_chan_connect()
1740 hdr->ident = l2cap_br_get_ident(); in bt_l2cap_br_chan_connect()
1741 hdr->len = sys_cpu_to_le16(sizeof(*req)); in bt_l2cap_br_chan_connect()
1744 req->psm = sys_cpu_to_le16(psm); in bt_l2cap_br_chan_connect()
1745 req->scid = sys_cpu_to_le16(BR_CHAN(chan)->rx.cid); in bt_l2cap_br_chan_connect()
1755 struct bt_conn *conn = l2cap->chan.chan.conn; in l2cap_br_conn_rsp()
1757 struct bt_l2cap_conn_rsp *rsp = (void *)buf->data; in l2cap_br_conn_rsp()
1761 if (buf->len < sizeof(*rsp)) { in l2cap_br_conn_rsp()
1766 dcid = sys_le16_to_cpu(rsp->dcid); in l2cap_br_conn_rsp()
1767 scid = sys_le16_to_cpu(rsp->scid); in l2cap_br_conn_rsp()
1768 result = sys_le16_to_cpu(rsp->result); in l2cap_br_conn_rsp()
1769 status = sys_le16_to_cpu(rsp->status); in l2cap_br_conn_rsp()
1782 k_work_cancel_delayable(&br_chan->rtx_work); in l2cap_br_conn_rsp()
1784 if (br_chan->state != BT_L2CAP_CONNECTING) { in l2cap_br_conn_rsp()
1786 bt_l2cap_chan_state_str(br_chan->state)); in l2cap_br_conn_rsp()
1792 br_chan->ident = 0U; in l2cap_br_conn_rsp()
1793 BR_CHAN(chan)->tx.cid = dcid; in l2cap_br_conn_rsp()
1796 atomic_clear_bit(BR_CHAN(chan)->flags, L2CAP_FLAG_CONN_PENDING); in l2cap_br_conn_rsp()
1799 k_work_reschedule(&br_chan->rtx_work, L2CAP_BR_CONN_TIMEOUT); in l2cap_br_conn_rsp()
1813 return -EINVAL; in bt_l2cap_br_chan_send_cb()
1820 if (!chan->conn || chan->conn->state != BT_CONN_CONNECTED) { in bt_l2cap_br_chan_send_cb()
1821 return -ENOTCONN; in bt_l2cap_br_chan_send_cb()
1824 if (atomic_test_bit(chan->status, BT_L2CAP_STATUS_SHUTDOWN)) { in bt_l2cap_br_chan_send_cb()
1825 return -ESHUTDOWN; in bt_l2cap_br_chan_send_cb()
1828 if (buf->len > br_chan->tx.mtu) { in bt_l2cap_br_chan_send_cb()
1829 return -EMSGSIZE; in bt_l2cap_br_chan_send_cb()
1832 return bt_l2cap_br_send_cb(br_chan->chan.conn, br_chan->tx.cid, buf, cb, user_data); in bt_l2cap_br_chan_send_cb()
1846 len = sys_le16_to_cpu(hdr->len); in l2cap_br_sig_handle()
1848 net_buf_simple_save(&buf->b, &state); in l2cap_br_sig_handle()
1850 switch (hdr->code) { in l2cap_br_sig_handle()
1852 l2cap_br_info_rsp(l2cap, hdr->ident, buf); in l2cap_br_sig_handle()
1855 l2cap_br_info_req(l2cap, hdr->ident, buf); in l2cap_br_sig_handle()
1858 l2cap_br_disconn_req(l2cap, hdr->ident, buf); in l2cap_br_sig_handle()
1861 l2cap_br_conn_req(l2cap, hdr->ident, buf); in l2cap_br_sig_handle()
1864 l2cap_br_conf_rsp(l2cap, hdr->ident, len, buf); in l2cap_br_sig_handle()
1867 l2cap_br_conf_req(l2cap, hdr->ident, len, buf); in l2cap_br_sig_handle()
1870 l2cap_br_disconn_rsp(l2cap, hdr->ident, buf); in l2cap_br_sig_handle()
1873 l2cap_br_conn_rsp(l2cap, hdr->ident, buf); in l2cap_br_sig_handle()
1876 LOG_WRN("Unknown/Unsupported L2CAP PDU code 0x%02x", hdr->code); in l2cap_br_sig_handle()
1877 l2cap_br_send_reject(l2cap->chan.chan.conn, hdr->ident, in l2cap_br_sig_handle()
1882 net_buf_simple_restore(&buf->b, &state); in l2cap_br_sig_handle()
1892 while (buf->len > 0) { in l2cap_br_recv()
1893 if (buf->len < sizeof(*hdr)) { in l2cap_br_recv()
1899 len = sys_le16_to_cpu(hdr->len); in l2cap_br_recv()
1901 LOG_DBG("Signaling code 0x%02x ident %u len %u", hdr->code, hdr->ident, len); in l2cap_br_recv()
1903 if (buf->len < len) { in l2cap_br_recv()
1904 LOG_ERR("L2CAP length is short (%u < %u)", buf->len, len); in l2cap_br_recv()
1908 if (!hdr->ident) { in l2cap_br_recv()
1926 if (BR_CHAN(chan)->state != BT_L2CAP_CONNECTING) { in l2cap_br_conn_pend()
1930 LOG_DBG("chan %p status 0x%02x encr 0x%02x", chan, status, chan->conn->encrypt); in l2cap_br_conn_pend()
1934 * Security procedure status is non-zero so respond with in l2cap_br_conn_pend()
1940 if (atomic_test_bit(BR_CHAN(chan)->flags, in l2cap_br_conn_pend()
1948 if (!chan->conn->encrypt) { in l2cap_br_conn_pend()
1963 } else if (atomic_test_and_clear_bit(BR_CHAN(chan)->flags, in l2cap_br_conn_pend()
1968 hdr->code = BT_L2CAP_CONN_REQ; in l2cap_br_conn_pend()
1969 hdr->ident = l2cap_br_get_ident(); in l2cap_br_conn_pend()
1970 hdr->len = sys_cpu_to_le16(sizeof(*req)); in l2cap_br_conn_pend()
1973 req->psm = sys_cpu_to_le16(BR_CHAN(chan)->psm); in l2cap_br_conn_pend()
1974 req->scid = sys_cpu_to_le16(BR_CHAN(chan)->rx.cid); in l2cap_br_conn_pend()
1985 SYS_SLIST_FOR_EACH_CONTAINER(&conn->channels, chan, node) { in l2cap_br_encrypt_change()
1988 if (chan->ops && chan->ops->encrypt_change) { in l2cap_br_encrypt_change()
1989 chan->ops->encrypt_change(chan, hci_status); in l2cap_br_encrypt_change()
1998 if (br_chan->rx.cid < L2CAP_BR_CID_DYN_START) { in check_fixed_channel()
2009 if (buf->len < sizeof(*hdr)) { in bt_l2cap_br_recv()
2016 cid = sys_le16_to_cpu(hdr->cid); in bt_l2cap_br_recv()
2031 chan->ops->recv(chan, buf); in bt_l2cap_br_recv()
2044 LOG_DBG("conn %p handle %u", conn, conn->handle); in l2cap_br_accept()
2049 if (l2cap->chan.chan.conn) { in l2cap_br_accept()
2053 l2cap->chan.chan.ops = &ops; in l2cap_br_accept()
2054 *chan = &l2cap->chan.chan; in l2cap_br_accept()
2055 atomic_set(l2cap->chan.flags, 0); in l2cap_br_accept()
2061 return -ENOMEM; in l2cap_br_accept()