Lines Matching +full:rx +full:- +full:wake +full:- +full:timeout

1 /* rfcomm.c - RFCOMM handling */
6 * SPDX-License-Identifier: Apache-2.0
39 #define RFCOMM_MAX_CREDITS (BT_BUF_ACL_RX_COUNT - 1)
54 /* Pool for dummy buffers to wake up the tx threads */
62 /* reversed, 8-bit, poly=0x07 */
109 while (len--) { in rfcomm_calc_fcs()
114 return (0xff - fcs); in rfcomm_calc_fcs()
122 while (len--) { in rfcomm_check_fcs()
136 for (; dlcs; dlcs = dlcs->_next) { in rfcomm_dlcs_lookup_dlci()
137 if (dlcs->dlci == dlci) { in rfcomm_dlcs_lookup_dlci()
155 if (dlcs->dlci == dlci) { in rfcomm_dlcs_remove_dlci()
156 dlcs->session->dlcs = dlcs->_next; in rfcomm_dlcs_remove_dlci()
160 for (tmp = dlcs, dlcs = dlcs->_next; dlcs; dlcs = dlcs->_next) { in rfcomm_dlcs_remove_dlci()
161 if (dlcs->dlci == dlci) { in rfcomm_dlcs_remove_dlci()
162 tmp->_next = dlcs->_next; in rfcomm_dlcs_remove_dlci()
175 for (server = servers; server; server = server->_next) { in rfcomm_server_lookup_channel()
176 if (server->channel == channel) { in rfcomm_server_lookup_channel()
192 if (session->br_chan.chan.conn == conn) { in rfcomm_sessions_lookup_bt_conn()
202 if (server->channel < RFCOMM_CHANNEL_START || in bt_rfcomm_server_register()
203 server->channel > RFCOMM_CHANNEL_END || !server->accept) { in bt_rfcomm_server_register()
204 return -EINVAL; in bt_rfcomm_server_register()
208 if (rfcomm_server_lookup_channel(server->channel)) { in bt_rfcomm_server_register()
210 return -EADDRINUSE; in bt_rfcomm_server_register()
213 LOG_DBG("Channel 0x%02x", server->channel); in bt_rfcomm_server_register()
215 server->_next = servers; in bt_rfcomm_server_register()
226 while (credits--) { in rfcomm_dlc_tx_give_credits()
227 k_sem_give(&dlc->tx_credits); in rfcomm_dlc_tx_give_credits()
230 LOG_DBG("dlc %p updated credits %u", dlc, k_sem_count_get(&dlc->tx_credits)); in rfcomm_dlc_tx_give_credits()
237 k_work_cancel_delayable(&dlc->rtx_work); in rfcomm_dlc_destroy()
238 dlc->state = BT_RFCOMM_STATE_IDLE; in rfcomm_dlc_destroy()
239 dlc->session = NULL; in rfcomm_dlc_destroy()
241 if (dlc->ops && dlc->ops->disconnected) { in rfcomm_dlc_destroy()
242 dlc->ops->disconnected(dlc); in rfcomm_dlc_destroy()
248 uint8_t old_state = dlc->state; in rfcomm_dlc_disconnect()
252 if (dlc->state == BT_RFCOMM_STATE_DISCONNECTED) { in rfcomm_dlc_disconnect()
256 dlc->state = BT_RFCOMM_STATE_DISCONNECTED; in rfcomm_dlc_disconnect()
260 /* Queue a dummy buffer to wake up and stop the in rfcomm_dlc_disconnect()
263 k_fifo_put(&dlc->tx_queue, net_buf_alloc(&dummy_pool, K_NO_WAIT)); in rfcomm_dlc_disconnect()
266 * dummy credit to wake it up. in rfcomm_dlc_disconnect()
269 k_sem_give(&dlc->session->fc); in rfcomm_dlc_disconnect()
283 if (session->state == BT_RFCOMM_STATE_DISCONNECTED) { in rfcomm_session_disconnected()
287 for (dlc = session->dlcs; dlc;) { in rfcomm_session_disconnected()
291 next = dlc->_next; in rfcomm_session_disconnected()
292 dlc->_next = NULL; in rfcomm_session_disconnected()
299 session->state = BT_RFCOMM_STATE_DISCONNECTED; in rfcomm_session_disconnected()
300 session->dlcs = NULL; in rfcomm_session_disconnected()
318 err = bt_l2cap_br_chan_send_cb(&session->br_chan.chan, buf, cb, user_data); in rfcomm_send_cb()
340 cr = BT_RFCOMM_CMD_CR(session->role); in rfcomm_send_sabm()
341 hdr->address = BT_RFCOMM_SET_ADDR(dlci, cr); in rfcomm_send_sabm()
342 hdr->control = BT_RFCOMM_SET_CTRL(BT_RFCOMM_SABM, BT_RFCOMM_PF_NON_UIH); in rfcomm_send_sabm()
343 hdr->length = BT_RFCOMM_SET_LEN_8(0); in rfcomm_send_sabm()
345 fcs = rfcomm_calc_fcs(BT_RFCOMM_FCS_LEN_NON_UIH, buf->data); in rfcomm_send_sabm()
362 cr = BT_RFCOMM_RESP_CR(session->role); in rfcomm_send_disc()
363 hdr->address = BT_RFCOMM_SET_ADDR(dlci, cr); in rfcomm_send_disc()
364 hdr->control = BT_RFCOMM_SET_CTRL(BT_RFCOMM_DISC, BT_RFCOMM_PF_NON_UIH); in rfcomm_send_disc()
365 hdr->length = BT_RFCOMM_SET_LEN_8(0); in rfcomm_send_disc()
366 fcs = rfcomm_calc_fcs(BT_RFCOMM_FCS_LEN_NON_UIH, buf->data); in rfcomm_send_disc()
374 if (session->dlcs) { in rfcomm_session_disconnect()
378 session->state = BT_RFCOMM_STATE_DISCONNECTING; in rfcomm_session_disconnect()
380 k_work_reschedule(&session->rtx_work, RFCOMM_DISC_TIMEOUT); in rfcomm_session_disconnect()
395 hdr_cr = BT_RFCOMM_UIH_CR(session->role); in rfcomm_make_uih_msg()
396 hdr->address = BT_RFCOMM_SET_ADDR(0, hdr_cr); in rfcomm_make_uih_msg()
397 hdr->control = BT_RFCOMM_SET_CTRL(BT_RFCOMM_UIH, BT_RFCOMM_PF_UIH); in rfcomm_make_uih_msg()
398 hdr->length = BT_RFCOMM_SET_LEN_8(sizeof(*msg_hdr) + len); in rfcomm_make_uih_msg()
401 msg_hdr->type = BT_RFCOMM_SET_MSG_TYPE(type, cr); in rfcomm_make_uih_msg()
402 msg_hdr->len = BT_RFCOMM_SET_LEN_8(len); in rfcomm_make_uih_msg()
414 session->mtu = MIN(session->br_chan.rx.mtu, in rfcomm_connected()
415 session->br_chan.tx.mtu) - in rfcomm_connected()
418 if (session->state == BT_RFCOMM_STATE_CONNECTING) { in rfcomm_connected()
429 k_work_cancel_delayable(&session->rtx_work); in rfcomm_disconnected()
431 session->state = BT_RFCOMM_STATE_IDLE; in rfcomm_disconnected()
437 struct bt_rfcomm_session *session = dlc->session; in rfcomm_dlc_rtx_timeout()
439 LOG_WRN("dlc %p state %d timeout", dlc, dlc->state); in rfcomm_dlc_rtx_timeout()
441 rfcomm_dlcs_remove_dlci(session->dlcs, dlc->dlci); in rfcomm_dlc_rtx_timeout()
453 dlc->dlci = dlci; in rfcomm_dlc_init()
454 dlc->session = session; in rfcomm_dlc_init()
455 dlc->rx_credit = RFCOMM_DEFAULT_CREDIT; in rfcomm_dlc_init()
456 dlc->state = BT_RFCOMM_STATE_INIT; in rfcomm_dlc_init()
457 dlc->role = role; in rfcomm_dlc_init()
458 k_work_init_delayable(&dlc->rtx_work, rfcomm_dlc_rtx_timeout); in rfcomm_dlc_init()
461 k_work_schedule(&dlc->rtx_work, RFCOMM_CONN_TIMEOUT); in rfcomm_dlc_init()
463 dlc->_next = session->dlcs; in rfcomm_dlc_init()
464 session->dlcs = dlc; in rfcomm_dlc_init()
481 if (server->accept(session->br_chan.chan.conn, &dlc) < 0) { in rfcomm_dlc_accept()
486 if (!BT_RFCOMM_CHECK_MTU(dlc->mtu)) { in rfcomm_dlc_accept()
492 dlc->mtu = MIN(dlc->mtu, session->mtu); in rfcomm_dlc_accept()
508 cr = BT_RFCOMM_RESP_CR(session->role); in rfcomm_send_dm()
509 hdr->address = BT_RFCOMM_SET_ADDR(dlci, cr); in rfcomm_send_dm()
511 hdr->control = BT_RFCOMM_SET_CTRL(BT_RFCOMM_DM, BT_RFCOMM_PF_NON_UIH); in rfcomm_send_dm()
512 hdr->length = BT_RFCOMM_SET_LEN_8(0); in rfcomm_send_dm()
513 fcs = rfcomm_calc_fcs(BT_RFCOMM_FCS_LEN_NON_UIH, buf->data); in rfcomm_send_dm()
525 k_sem_take(&dlc->tx_credits, K_FOREVER); in rfcomm_check_fc()
527 if (dlc->session->cfc == BT_RFCOMM_CFC_SUPPORTED) { in rfcomm_check_fc()
531 k_sem_take(&dlc->session->fc, K_FOREVER); in rfcomm_check_fc()
538 k_sem_give(&dlc->session->fc); in rfcomm_check_fc()
539 k_sem_give(&dlc->tx_credits); in rfcomm_check_fc()
546 if ((buf == NULL) || (buf->len == 0)) { in bt_rfcomm_tx_destroy()
550 if (dlc && dlc->ops && dlc->ops->sent) { in bt_rfcomm_tx_destroy()
551 dlc->ops->sent(dlc, -ESHUTDOWN); in bt_rfcomm_tx_destroy()
567 if (dlc && dlc->ops && dlc->ops->sent) { in rfcomm_sent()
568 dlc->ops->sent(dlc, err); in rfcomm_sent()
575 k_timeout_t timeout = K_FOREVER; in rfcomm_dlc_tx_thread() local
580 while (dlc->state == BT_RFCOMM_STATE_CONNECTED || in rfcomm_dlc_tx_thread()
581 dlc->state == BT_RFCOMM_STATE_USER_DISCONNECT) { in rfcomm_dlc_tx_thread()
584 buf = k_fifo_get(&dlc->tx_queue, timeout); in rfcomm_dlc_tx_thread()
586 if ((dlc->state != BT_RFCOMM_STATE_CONNECTED && in rfcomm_dlc_tx_thread()
587 dlc->state != BT_RFCOMM_STATE_USER_DISCONNECT) || in rfcomm_dlc_tx_thread()
588 !buf || !buf->len) { in rfcomm_dlc_tx_thread()
597 if (dlc->state != BT_RFCOMM_STATE_CONNECTED && in rfcomm_dlc_tx_thread()
598 dlc->state != BT_RFCOMM_STATE_USER_DISCONNECT) { in rfcomm_dlc_tx_thread()
604 if (rfcomm_send_cb(dlc->session, buf, rfcomm_sent, dlc) < 0) { in rfcomm_dlc_tx_thread()
606 dlc->state = BT_RFCOMM_STATE_DISCONNECTED; in rfcomm_dlc_tx_thread()
611 if (dlc->state == BT_RFCOMM_STATE_USER_DISCONNECT) { in rfcomm_dlc_tx_thread()
612 timeout = K_NO_WAIT; in rfcomm_dlc_tx_thread()
616 LOG_DBG("dlc %p disconnected - cleaning up", dlc); in rfcomm_dlc_tx_thread()
619 while ((buf = k_fifo_get(&dlc->tx_queue, K_NO_WAIT))) { in rfcomm_dlc_tx_thread()
624 if (dlc->state == BT_RFCOMM_STATE_USER_DISCONNECT) { in rfcomm_dlc_tx_thread()
625 dlc->state = BT_RFCOMM_STATE_DISCONNECTING; in rfcomm_dlc_tx_thread()
628 if (dlc->state == BT_RFCOMM_STATE_DISCONNECTING) { in rfcomm_dlc_tx_thread()
629 rfcomm_send_disc(dlc->session, dlc->dlci); in rfcomm_dlc_tx_thread()
630 k_work_reschedule(&dlc->rtx_work, RFCOMM_DISC_TIMEOUT); in rfcomm_dlc_tx_thread()
647 cr = BT_RFCOMM_RESP_CR(session->role); in rfcomm_send_ua()
648 hdr->address = BT_RFCOMM_SET_ADDR(dlci, cr); in rfcomm_send_ua()
649 hdr->control = BT_RFCOMM_SET_CTRL(BT_RFCOMM_UA, BT_RFCOMM_PF_NON_UIH); in rfcomm_send_ua()
650 hdr->length = BT_RFCOMM_SET_LEN_8(0); in rfcomm_send_ua()
652 fcs = rfcomm_calc_fcs(BT_RFCOMM_FCS_LEN_NON_UIH, buf->data); in rfcomm_send_ua()
665 buf = rfcomm_make_uih_msg(dlc->session, cr, BT_RFCOMM_MSC, in rfcomm_send_msc()
670 msc->dlci = BT_RFCOMM_SET_ADDR(dlc->dlci, 1); in rfcomm_send_msc()
671 msc->v24_signal = v24_signal; in rfcomm_send_msc()
673 fcs = rfcomm_calc_fcs(BT_RFCOMM_FCS_LEN_UIH, buf->data); in rfcomm_send_msc()
676 return rfcomm_send(dlc->session, buf); in rfcomm_send_msc()
686 buf = rfcomm_make_uih_msg(dlc->session, cr, BT_RFCOMM_RLS, in rfcomm_send_rls()
691 rls->dlci = BT_RFCOMM_SET_ADDR(dlc->dlci, 1); in rfcomm_send_rls()
692 rls->line_status = line_status; in rfcomm_send_rls()
694 fcs = rfcomm_calc_fcs(BT_RFCOMM_FCS_LEN_UIH, buf->data); in rfcomm_send_rls()
697 return rfcomm_send(dlc->session, buf); in rfcomm_send_rls()
710 fcs = rfcomm_calc_fcs(BT_RFCOMM_FCS_LEN_UIH, buf->data); in rfcomm_send_rpn()
726 fcs = rfcomm_calc_fcs(BT_RFCOMM_FCS_LEN_UIH, buf->data); in rfcomm_send_test()
742 fcs = rfcomm_calc_fcs(BT_RFCOMM_FCS_LEN_UIH, buf->data); in rfcomm_send_nsc()
755 fcs = rfcomm_calc_fcs(BT_RFCOMM_FCS_LEN_UIH, buf->data); in rfcomm_send_fcon()
768 fcs = rfcomm_calc_fcs(BT_RFCOMM_FCS_LEN_UIH, buf->data); in rfcomm_send_fcoff()
776 dlc->state = BT_RFCOMM_STATE_CONNECTED; in rfcomm_dlc_connected()
780 if (dlc->session->cfc == BT_RFCOMM_CFC_UNKNOWN) { in rfcomm_dlc_connected()
784 dlc->session->cfc = BT_RFCOMM_CFC_NOT_SUPPORTED; in rfcomm_dlc_connected()
787 if (dlc->session->cfc == BT_RFCOMM_CFC_NOT_SUPPORTED) { in rfcomm_dlc_connected()
789 rfcomm_send_fcon(dlc->session, BT_RFCOMM_MSG_CMD_CR); in rfcomm_dlc_connected()
791 k_sem_init(&dlc->tx_credits, 0, 1); in rfcomm_dlc_connected()
795 k_work_cancel_delayable(&dlc->rtx_work); in rfcomm_dlc_connected()
797 k_fifo_init(&dlc->tx_queue); in rfcomm_dlc_connected()
798 k_thread_create(&dlc->tx_thread, dlc->stack, in rfcomm_dlc_connected()
799 K_KERNEL_STACK_SIZEOF(dlc->stack), in rfcomm_dlc_connected()
802 k_thread_name_set(&dlc->tx_thread, "BT DLC"); in rfcomm_dlc_connected()
804 if (dlc->ops && dlc->ops->connected) { in rfcomm_dlc_connected()
805 dlc->ops->connected(dlc); in rfcomm_dlc_connected()
817 struct bt_conn *conn = dlc->session->br_chan.chan.conn; in rfcomm_dlc_security()
826 if (conn->sec_level >= dlc->required_sec_level) { in rfcomm_dlc_security()
830 if (!bt_conn_set_security(conn, dlc->required_sec_level)) { in rfcomm_dlc_security()
837 atomic_set_bit(conn->flags, BT_CONN_BR_GENERAL_BONDING); in rfcomm_dlc_security()
850 rfcomm_dlcs_remove_dlci(dlc->session->dlcs, dlc->dlci); in rfcomm_dlc_drop()
858 switch (dlc->state) { in rfcomm_dlc_close()
860 if (dlc->role == BT_RFCOMM_ROLE_ACCEPTOR) { in rfcomm_dlc_close()
861 rfcomm_send_dm(dlc->session, dlc->dlci); in rfcomm_dlc_close()
869 dlc->state = BT_RFCOMM_STATE_DISCONNECTING; in rfcomm_dlc_close()
870 rfcomm_send_disc(dlc->session, dlc->dlci); in rfcomm_dlc_close()
871 k_work_reschedule(&dlc->rtx_work, RFCOMM_DISC_TIMEOUT); in rfcomm_dlc_close()
874 dlc->state = BT_RFCOMM_STATE_DISCONNECTING; in rfcomm_dlc_close()
876 /* Queue a dummy buffer to wake up and stop the in rfcomm_dlc_close()
879 k_fifo_put(&dlc->tx_queue, in rfcomm_dlc_close()
883 * dummy credit to wake it up. in rfcomm_dlc_close()
892 return -EINVAL; in rfcomm_dlc_close()
905 session->state = BT_RFCOMM_STATE_CONNECTED; in rfcomm_handle_sabm()
910 dlc = rfcomm_dlcs_lookup_dlci(session->dlcs, dlci); in rfcomm_handle_sabm()
922 dlc->state = BT_RFCOMM_STATE_SECURITY_PENDING; in rfcomm_handle_sabm()
938 k_work_cancel_delayable(&session->rtx_work); in rfcomm_handle_sabm()
950 buf = rfcomm_make_uih_msg(dlc->session, cr, BT_RFCOMM_PN, sizeof(*pn)); in rfcomm_send_pn()
952 LOG_DBG("mtu %x", dlc->mtu); in rfcomm_send_pn()
955 pn->dlci = dlc->dlci; in rfcomm_send_pn()
956 pn->mtu = sys_cpu_to_le16(dlc->mtu); in rfcomm_send_pn()
957 if (dlc->state == BT_RFCOMM_STATE_CONFIG && in rfcomm_send_pn()
958 (dlc->session->cfc == BT_RFCOMM_CFC_UNKNOWN || in rfcomm_send_pn()
959 dlc->session->cfc == BT_RFCOMM_CFC_SUPPORTED)) { in rfcomm_send_pn()
960 pn->credits = dlc->rx_credit; in rfcomm_send_pn()
962 pn->flow_ctrl = BT_RFCOMM_PN_CFC_CMD; in rfcomm_send_pn()
964 pn->flow_ctrl = BT_RFCOMM_PN_CFC_RESP; in rfcomm_send_pn()
970 pn->credits = 0U; in rfcomm_send_pn()
971 pn->flow_ctrl = 0U; in rfcomm_send_pn()
973 pn->max_retrans = 0U; in rfcomm_send_pn()
974 pn->ack_timer = 0U; in rfcomm_send_pn()
975 pn->priority = 0U; in rfcomm_send_pn()
977 fcs = rfcomm_calc_fcs(BT_RFCOMM_FCS_LEN_UIH, buf->data); in rfcomm_send_pn()
980 return rfcomm_send(dlc->session, buf); in rfcomm_send_pn()
994 cr = BT_RFCOMM_UIH_CR(dlc->session->role); in rfcomm_send_credit()
995 hdr->address = BT_RFCOMM_SET_ADDR(dlc->dlci, cr); in rfcomm_send_credit()
996 hdr->control = BT_RFCOMM_SET_CTRL(BT_RFCOMM_UIH, in rfcomm_send_credit()
998 hdr->length = BT_RFCOMM_SET_LEN_8(0); in rfcomm_send_credit()
1000 fcs = rfcomm_calc_fcs(BT_RFCOMM_FCS_LEN_UIH, buf->data); in rfcomm_send_credit()
1003 return rfcomm_send(dlc->session, buf); in rfcomm_send_credit()
1015 dlc->mtu = MIN(dlc->mtu, dlc->session->mtu); in rfcomm_dlc_start()
1016 dlc->state = BT_RFCOMM_STATE_CONFIG; in rfcomm_dlc_start()
1020 dlc->state = BT_RFCOMM_STATE_SECURITY_PENDING; in rfcomm_dlc_start()
1024 return -EIO; in rfcomm_dlc_start()
1036 switch (session->state) { in rfcomm_handle_ua()
1038 session->state = BT_RFCOMM_STATE_CONNECTED; in rfcomm_handle_ua()
1039 for (dlc = session->dlcs; dlc; dlc = next) { in rfcomm_handle_ua()
1040 next = dlc->_next; in rfcomm_handle_ua()
1041 if (dlc->role == BT_RFCOMM_ROLE_INITIATOR && in rfcomm_handle_ua()
1042 dlc->state == BT_RFCOMM_STATE_INIT) { in rfcomm_handle_ua()
1052 session->state = BT_RFCOMM_STATE_DISCONNECTED; in rfcomm_handle_ua()
1054 k_work_cancel_delayable(&session->rtx_work); in rfcomm_handle_ua()
1055 err = bt_l2cap_chan_disconnect(&session->br_chan.chan); in rfcomm_handle_ua()
1057 session->state = BT_RFCOMM_STATE_IDLE; in rfcomm_handle_ua()
1064 dlc = rfcomm_dlcs_lookup_dlci(session->dlcs, dlci); in rfcomm_handle_ua()
1069 switch (dlc->state) { in rfcomm_handle_ua()
1089 dlc = rfcomm_dlcs_remove_dlci(session->dlcs, dlci); in rfcomm_handle_dm()
1101 struct bt_rfcomm_msc *msc = (void *)buf->data; in rfcomm_handle_msc()
1103 uint8_t dlci = BT_RFCOMM_GET_DLCI(msc->dlci); in rfcomm_handle_msc()
1107 dlc = rfcomm_dlcs_lookup_dlci(session->dlcs, dlci); in rfcomm_handle_msc()
1116 if (dlc->session->cfc == BT_RFCOMM_CFC_NOT_SUPPORTED) { in rfcomm_handle_msc()
1118 if (BT_RFCOMM_GET_FC(msc->v24_signal)) { in rfcomm_handle_msc()
1120 * Take the semaphore with timeout K_NO_WAIT so that in rfcomm_handle_msc()
1122 * before sending the data. K_NO_WAIT timeout will make in rfcomm_handle_msc()
1123 * sure that RX thread will not be blocked while taking in rfcomm_handle_msc()
1126 k_sem_take(&dlc->tx_credits, K_NO_WAIT); in rfcomm_handle_msc()
1131 k_sem_give(&dlc->tx_credits); in rfcomm_handle_msc()
1135 rfcomm_send_msc(dlc, BT_RFCOMM_MSG_RESP_CR, msc->v24_signal); in rfcomm_handle_msc()
1141 struct bt_rfcomm_rls *rls = (void *)buf->data; in rfcomm_handle_rls()
1142 uint8_t dlci = BT_RFCOMM_GET_DLCI(rls->dlci); in rfcomm_handle_rls()
1152 dlc = rfcomm_dlcs_lookup_dlci(session->dlcs, dlci); in rfcomm_handle_rls()
1158 rfcomm_send_rls(dlc, BT_RFCOMM_MSG_RESP_CR, rls->line_status); in rfcomm_handle_rls()
1164 struct bt_rfcomm_rpn default_rpn, *rpn = (void *)buf->data; in rfcomm_handle_rpn()
1165 uint8_t dlci = BT_RFCOMM_GET_DLCI(rpn->dlci); in rfcomm_handle_rpn()
1168 uint8_t value_len = buf->len - 1; in rfcomm_handle_rpn()
1179 rpn->param_mask = sys_cpu_to_le16(BT_RFCOMM_RPN_PARAM_MASK_ALL); in rfcomm_handle_rpn()
1210 struct bt_rfcomm_pn *pn = (void *)buf->data; in rfcomm_handle_pn()
1213 dlc = rfcomm_dlcs_lookup_dlci(session->dlcs, pn->dlci); in rfcomm_handle_pn()
1220 if (!BT_RFCOMM_CHECK_MTU(pn->mtu)) { in rfcomm_handle_pn()
1221 LOG_ERR("Invalid mtu %d", pn->mtu); in rfcomm_handle_pn()
1222 rfcomm_send_dm(session, pn->dlci); in rfcomm_handle_pn()
1226 dlc = rfcomm_dlc_accept(session, pn->dlci); in rfcomm_handle_pn()
1228 rfcomm_send_dm(session, pn->dlci); in rfcomm_handle_pn()
1234 dlc->mtu = MIN(dlc->mtu, sys_le16_to_cpu(pn->mtu)); in rfcomm_handle_pn()
1236 if (pn->flow_ctrl == BT_RFCOMM_PN_CFC_CMD) { in rfcomm_handle_pn()
1237 if (session->cfc == BT_RFCOMM_CFC_UNKNOWN) { in rfcomm_handle_pn()
1238 session->cfc = BT_RFCOMM_CFC_SUPPORTED; in rfcomm_handle_pn()
1240 k_sem_init(&dlc->tx_credits, 0, K_SEM_MAX_LIMIT); in rfcomm_handle_pn()
1241 rfcomm_dlc_tx_give_credits(dlc, pn->credits); in rfcomm_handle_pn()
1243 session->cfc = BT_RFCOMM_CFC_NOT_SUPPORTED; in rfcomm_handle_pn()
1246 dlc->state = BT_RFCOMM_STATE_CONFIG; in rfcomm_handle_pn()
1249 k_work_cancel_delayable(&session->rtx_work); in rfcomm_handle_pn()
1253 if (!BT_RFCOMM_CHECK_MTU(pn->mtu)) { in rfcomm_handle_pn()
1254 LOG_ERR("Invalid mtu %d", pn->mtu); in rfcomm_handle_pn()
1258 dlc->mtu = MIN(dlc->mtu, sys_le16_to_cpu(pn->mtu)); in rfcomm_handle_pn()
1261 if (dlc->state != BT_RFCOMM_STATE_CONFIG) { in rfcomm_handle_pn()
1265 dlc->mtu = MIN(dlc->mtu, sys_le16_to_cpu(pn->mtu)); in rfcomm_handle_pn()
1266 if (pn->flow_ctrl == BT_RFCOMM_PN_CFC_RESP) { in rfcomm_handle_pn()
1267 if (session->cfc == BT_RFCOMM_CFC_UNKNOWN) { in rfcomm_handle_pn()
1268 session->cfc = BT_RFCOMM_CFC_SUPPORTED; in rfcomm_handle_pn()
1270 k_sem_init(&dlc->tx_credits, 0, K_SEM_MAX_LIMIT); in rfcomm_handle_pn()
1271 rfcomm_dlc_tx_give_credits(dlc, pn->credits); in rfcomm_handle_pn()
1273 session->cfc = BT_RFCOMM_CFC_NOT_SUPPORTED; in rfcomm_handle_pn()
1276 dlc->state = BT_RFCOMM_STATE_CONNECTING; in rfcomm_handle_pn()
1277 rfcomm_send_sabm(session, dlc->dlci); in rfcomm_handle_pn()
1289 dlc = rfcomm_dlcs_remove_dlci(session->dlcs, dlci); in rfcomm_handle_disc()
1298 if (!session->dlcs) { in rfcomm_handle_disc()
1300 k_work_reschedule(&dlc->session->rtx_work, in rfcomm_handle_disc()
1305 k_work_cancel_delayable(&session->rtx_work); in rfcomm_handle_disc()
1317 if (buf->len < sizeof(*hdr)) { in rfcomm_handle_msg()
1323 msg_type = BT_RFCOMM_GET_MSG_TYPE(hdr->type); in rfcomm_handle_msg()
1324 cr = BT_RFCOMM_GET_MSG_CR(hdr->type); in rfcomm_handle_msg()
1325 len = BT_RFCOMM_GET_LEN(hdr->len); in rfcomm_handle_msg()
1346 rfcomm_send_test(session, BT_RFCOMM_MSG_RESP_CR, buf->data, in rfcomm_handle_msg()
1347 buf->len - 1); in rfcomm_handle_msg()
1350 if (session->cfc == BT_RFCOMM_CFC_SUPPORTED) { in rfcomm_handle_msg()
1362 k_sem_give(&session->fc); in rfcomm_handle_msg()
1366 if (session->cfc == BT_RFCOMM_CFC_SUPPORTED) { in rfcomm_handle_msg()
1375 /* Take the semaphore with timeout K_NO_WAIT so that all the in rfcomm_handle_msg()
1377 * sem_take before sending the data. K_NO_WAIT timeout will in rfcomm_handle_msg()
1378 * make sure that RX thread will not be blocked while taking in rfcomm_handle_msg()
1381 k_sem_take(&session->fc, K_NO_WAIT); in rfcomm_handle_msg()
1386 rfcomm_send_nsc(session, hdr->type); in rfcomm_handle_msg()
1395 if (dlc->session->cfc == BT_RFCOMM_CFC_NOT_SUPPORTED) { in rfcomm_dlc_update_credits()
1399 LOG_DBG("dlc %p credits %u", dlc, dlc->rx_credit); in rfcomm_dlc_update_credits()
1402 if (dlc->rx_credit > RFCOMM_CREDITS_THRESHOLD) { in rfcomm_dlc_update_credits()
1407 credits = RFCOMM_MAX_CREDITS - dlc->rx_credit; in rfcomm_dlc_update_credits()
1408 dlc->rx_credit += credits; in rfcomm_dlc_update_credits()
1421 dlc = rfcomm_dlcs_lookup_dlci(session->dlcs, dlci); in rfcomm_handle_data()
1428 LOG_DBG("dlc %p rx credit %d", dlc, dlc->rx_credit); in rfcomm_handle_data()
1430 if (dlc->state != BT_RFCOMM_STATE_CONNECTED) { in rfcomm_handle_data()
1435 if (buf->len == 0) { in rfcomm_handle_data()
1442 if (buf->len > BT_RFCOMM_FCS_SIZE) { in rfcomm_handle_data()
1443 if (dlc->session->cfc == BT_RFCOMM_CFC_SUPPORTED && in rfcomm_handle_data()
1444 !dlc->rx_credit) { in rfcomm_handle_data()
1445 LOG_ERR("Data recvd when rx credit is 0"); in rfcomm_handle_data()
1451 buf->len -= BT_RFCOMM_FCS_SIZE; in rfcomm_handle_data()
1452 if (dlc->ops && dlc->ops->recv) { in rfcomm_handle_data()
1453 dlc->ops->recv(dlc, buf); in rfcomm_handle_data()
1456 dlc->rx_credit--; in rfcomm_handle_data()
1466 return -EINVAL; in bt_rfcomm_dlc_send()
1469 LOG_DBG("dlc %p tx credit %d", dlc, k_sem_count_get(&dlc->tx_credits)); in bt_rfcomm_dlc_send()
1471 if (dlc->state != BT_RFCOMM_STATE_CONNECTED) { in bt_rfcomm_dlc_send()
1472 return -ENOTCONN; in bt_rfcomm_dlc_send()
1475 if (buf->len > dlc->mtu) { in bt_rfcomm_dlc_send()
1476 return -EMSGSIZE; in bt_rfcomm_dlc_send()
1480 if (buf->len > BT_RFCOMM_MAX_LEN_8) { in bt_rfcomm_dlc_send()
1482 net_buf_push_le16(buf, BT_RFCOMM_SET_LEN_16(buf->len)); in bt_rfcomm_dlc_send()
1484 net_buf_push_u8(buf, BT_RFCOMM_SET_LEN_8(buf->len)); in bt_rfcomm_dlc_send()
1491 cr = BT_RFCOMM_UIH_CR(dlc->session->role); in bt_rfcomm_dlc_send()
1492 net_buf_push_u8(buf, BT_RFCOMM_SET_ADDR(dlc->dlci, cr)); in bt_rfcomm_dlc_send()
1494 fcs = rfcomm_calc_fcs(BT_RFCOMM_FCS_LEN_UIH, buf->data); in bt_rfcomm_dlc_send()
1497 k_fifo_put(&dlc->tx_queue, buf); in bt_rfcomm_dlc_send()
1499 return buf->len; in bt_rfcomm_dlc_send()
1505 struct bt_rfcomm_hdr *hdr = (void *)buf->data; in rfcomm_recv()
1506 struct bt_rfcomm_hdr_ext *hdr_ext = (void *)buf->data; in rfcomm_recv()
1512 if (buf->len < (sizeof(*hdr) + sizeof(fcs))) { in rfcomm_recv()
1517 dlci = BT_RFCOMM_GET_DLCI(hdr->address); in rfcomm_recv()
1518 frame_type = BT_RFCOMM_GET_FRAME_TYPE(hdr->control); in rfcomm_recv()
1522 if (BT_RFCOMM_LEN_EXTENDED(hdr->length)) { in rfcomm_recv()
1523 msg_len = BT_RFCOMM_GET_LEN_EXTENDED(hdr_ext->hdr.length, hdr_ext->second_length); in rfcomm_recv()
1526 msg_len = BT_RFCOMM_GET_LEN(hdr->length); in rfcomm_recv()
1530 if (buf->len < (hdr_len + msg_len + sizeof(fcs))) { in rfcomm_recv()
1531 LOG_ERR("Too small RFCOMM information (%d < %d)", buf->len, in rfcomm_recv()
1537 fcs = *(net_buf_tail(buf) - sizeof(fcs)); in rfcomm_recv()
1538 if (!rfcomm_check_fcs(fcs_len, buf->data, fcs)) { in rfcomm_recv()
1553 rfcomm_handle_data(session, buf, dlci, BT_RFCOMM_GET_PF(hdr->control)); in rfcomm_recv()
1577 struct bt_conn *conn = chan->conn; in rfcomm_encrypt_change()
1580 LOG_DBG("session %p status 0x%02x encr 0x%02x", session, hci_status, conn->encrypt); in rfcomm_encrypt_change()
1582 for (dlc = session->dlcs; dlc; dlc = next) { in rfcomm_encrypt_change()
1583 next = dlc->_next; in rfcomm_encrypt_change()
1585 if (dlc->state != BT_RFCOMM_STATE_SECURITY_PENDING) { in rfcomm_encrypt_change()
1589 if (hci_status || !conn->encrypt || in rfcomm_encrypt_change()
1590 conn->sec_level < dlc->required_sec_level) { in rfcomm_encrypt_change()
1595 if (dlc->role == BT_RFCOMM_ROLE_ACCEPTOR) { in rfcomm_encrypt_change()
1596 rfcomm_send_ua(session, dlc->dlci); in rfcomm_encrypt_change()
1599 dlc->mtu = MIN(dlc->mtu, session->mtu); in rfcomm_encrypt_change()
1600 dlc->state = BT_RFCOMM_STATE_CONFIG; in rfcomm_encrypt_change()
1610 LOG_WRN("session %p state %d timeout", session, session->state); in rfcomm_session_rtx_timeout()
1612 switch (session->state) { in rfcomm_session_rtx_timeout()
1617 session->state = BT_RFCOMM_STATE_DISCONNECTED; in rfcomm_session_rtx_timeout()
1618 if (bt_l2cap_chan_disconnect(&session->br_chan.chan) < 0) { in rfcomm_session_rtx_timeout()
1619 session->state = BT_RFCOMM_STATE_IDLE; in rfcomm_session_rtx_timeout()
1638 if (session->br_chan.chan.conn) { in rfcomm_session_new()
1644 session->br_chan.chan.ops = &ops; in rfcomm_session_new()
1645 session->br_chan.rx.mtu = CONFIG_BT_RFCOMM_L2CAP_MTU; in rfcomm_session_new()
1646 session->state = BT_RFCOMM_STATE_INIT; in rfcomm_session_new()
1647 session->role = role; in rfcomm_session_new()
1648 session->cfc = BT_RFCOMM_CFC_UNKNOWN; in rfcomm_session_new()
1649 k_work_init_delayable(&session->rtx_work, in rfcomm_session_new()
1651 k_sem_init(&session->fc, 0, 1); in rfcomm_session_new()
1670 return -EINVAL; in bt_rfcomm_dlc_connect()
1673 if (!conn || conn->state != BT_CONN_CONNECTED) { in bt_rfcomm_dlc_connect()
1674 return -ENOTCONN; in bt_rfcomm_dlc_connect()
1678 return -EINVAL; in bt_rfcomm_dlc_connect()
1681 if (!BT_RFCOMM_CHECK_MTU(dlc->mtu)) { in bt_rfcomm_dlc_connect()
1682 return -EINVAL; in bt_rfcomm_dlc_connect()
1689 return -ENOMEM; in bt_rfcomm_dlc_connect()
1693 dlci = BT_RFCOMM_DLCI(session->role, channel); in bt_rfcomm_dlc_connect()
1695 if (rfcomm_dlcs_lookup_dlci(session->dlcs, dlci)) { in bt_rfcomm_dlc_connect()
1696 return -EBUSY; in bt_rfcomm_dlc_connect()
1701 switch (session->state) { in bt_rfcomm_dlc_connect()
1703 if (session->role == BT_RFCOMM_ROLE_ACCEPTOR) { in bt_rfcomm_dlc_connect()
1707 chan = &session->br_chan.chan; in bt_rfcomm_dlc_connect()
1708 BR_CHAN(chan)->required_sec_level = dlc->required_sec_level; in bt_rfcomm_dlc_connect()
1711 session->state = BT_RFCOMM_STATE_IDLE; in bt_rfcomm_dlc_connect()
1714 session->state = BT_RFCOMM_STATE_CONNECTING; in bt_rfcomm_dlc_connect()
1724 k_work_cancel_delayable(&session->rtx_work); in bt_rfcomm_dlc_connect()
1727 LOG_ERR("Invalid session state %d", session->state); in bt_rfcomm_dlc_connect()
1728 ret = -EINVAL; in bt_rfcomm_dlc_connect()
1735 rfcomm_dlcs_remove_dlci(session->dlcs, dlc->dlci); in bt_rfcomm_dlc_connect()
1736 dlc->state = BT_RFCOMM_STATE_IDLE; in bt_rfcomm_dlc_connect()
1737 dlc->session = NULL; in bt_rfcomm_dlc_connect()
1746 return -EINVAL; in bt_rfcomm_dlc_disconnect()
1749 if (dlc->state == BT_RFCOMM_STATE_CONNECTED) { in bt_rfcomm_dlc_disconnect()
1752 * Queue a dummy buffer (in case if queue is empty) to wake up in bt_rfcomm_dlc_disconnect()
1755 dlc->state = BT_RFCOMM_STATE_USER_DISCONNECT; in bt_rfcomm_dlc_disconnect()
1756 k_fifo_put(&dlc->tx_queue, in bt_rfcomm_dlc_disconnect()
1759 k_work_reschedule(&dlc->rtx_work, RFCOMM_DISC_TIMEOUT); in bt_rfcomm_dlc_disconnect()
1776 *chan = &session->br_chan.chan; in rfcomm_accept()
1782 return -ENOMEM; in rfcomm_accept()