/* rfcomm.c - RFCOMM handling */

/*
 * Copyright (c) 2016 Intel Corporation
 *
 * SPDX-License-Identifier: Apache-2.0
 */

#include <zephyr/kernel.h>
#include <string.h>
#include <errno.h>
#include <zephyr/sys/atomic.h>
#include <zephyr/sys/byteorder.h>
#include <zephyr/sys/util.h>
#include <zephyr/debug/stack.h>

#include <zephyr/bluetooth/hci.h>
#include <zephyr/bluetooth/bluetooth.h>
#include <zephyr/bluetooth/conn.h>
#include <zephyr/drivers/bluetooth/hci_driver.h>
#include <zephyr/bluetooth/l2cap.h>

#define BT_DBG_ENABLED IS_ENABLED(CONFIG_BT_DEBUG_RFCOMM)
#define LOG_MODULE_NAME bt_rfcomm
#include "common/log.h"

#include <zephyr/bluetooth/rfcomm.h>

#include "hci_core.h"
#include "conn_internal.h"
#include "l2cap_internal.h"
#include "rfcomm_internal.h"

#define RFCOMM_CHANNEL_START	0x01
#define RFCOMM_CHANNEL_END	0x1e

#define RFCOMM_MIN_MTU		BT_RFCOMM_SIG_MIN_MTU
#define RFCOMM_DEFAULT_MTU	127

#define RFCOMM_MAX_CREDITS		(CONFIG_BT_BUF_ACL_RX_COUNT - 1)
#define RFCOMM_CREDITS_THRESHOLD	(RFCOMM_MAX_CREDITS / 2)
#define RFCOMM_DEFAULT_CREDIT		RFCOMM_MAX_CREDITS

#define RFCOMM_CONN_TIMEOUT     K_SECONDS(60)
#define RFCOMM_DISC_TIMEOUT     K_SECONDS(20)
#define RFCOMM_IDLE_TIMEOUT     K_SECONDS(2)

#define DLC_RTX(_w) CONTAINER_OF(_w, struct bt_rfcomm_dlc, rtx_work)
#define SESSION_RTX(_w) CONTAINER_OF(_w, struct bt_rfcomm_session, rtx_work)

static struct bt_rfcomm_server *servers;

/* Pool for dummy buffers to wake up the tx threads */
NET_BUF_POOL_DEFINE(dummy_pool, CONFIG_BT_MAX_CONN, 0, 0, NULL);

#define RFCOMM_SESSION(_ch) CONTAINER_OF(_ch, \
					 struct bt_rfcomm_session, br_chan.chan)

static struct bt_rfcomm_session bt_rfcomm_pool[CONFIG_BT_MAX_CONN];

/* reversed, 8-bit, poly=0x07 */
static const uint8_t rfcomm_crc_table[256] = {
	0x00, 0x91, 0xe3, 0x72, 0x07, 0x96, 0xe4, 0x75,
	0x0e, 0x9f, 0xed, 0x7c, 0x09, 0x98, 0xea, 0x7b,
	0x1c, 0x8d, 0xff, 0x6e, 0x1b, 0x8a, 0xf8, 0x69,
	0x12, 0x83, 0xf1, 0x60, 0x15, 0x84, 0xf6, 0x67,

	0x38, 0xa9, 0xdb, 0x4a, 0x3f, 0xae, 0xdc, 0x4d,
	0x36, 0xa7, 0xd5, 0x44, 0x31, 0xa0, 0xd2, 0x43,
	0x24, 0xb5, 0xc7, 0x56, 0x23, 0xb2, 0xc0, 0x51,
	0x2a, 0xbb, 0xc9, 0x58, 0x2d, 0xbc, 0xce, 0x5f,

	0x70, 0xe1, 0x93, 0x02, 0x77, 0xe6, 0x94, 0x05,
	0x7e, 0xef, 0x9d, 0x0c, 0x79, 0xe8, 0x9a, 0x0b,
	0x6c, 0xfd, 0x8f, 0x1e, 0x6b, 0xfa, 0x88, 0x19,
	0x62, 0xf3, 0x81, 0x10, 0x65, 0xf4, 0x86, 0x17,

	0x48, 0xd9, 0xab, 0x3a, 0x4f, 0xde, 0xac, 0x3d,
	0x46, 0xd7, 0xa5, 0x34, 0x41, 0xd0, 0xa2, 0x33,
	0x54, 0xc5, 0xb7, 0x26, 0x53, 0xc2, 0xb0, 0x21,
	0x5a, 0xcb, 0xb9, 0x28, 0x5d, 0xcc, 0xbe, 0x2f,

	0xe0, 0x71, 0x03, 0x92, 0xe7, 0x76, 0x04, 0x95,
	0xee, 0x7f, 0x0d, 0x9c, 0xe9, 0x78, 0x0a, 0x9b,
	0xfc, 0x6d, 0x1f, 0x8e, 0xfb, 0x6a, 0x18, 0x89,
	0xf2, 0x63, 0x11, 0x80, 0xf5, 0x64, 0x16, 0x87,

	0xd8, 0x49, 0x3b, 0xaa, 0xdf, 0x4e, 0x3c, 0xad,
	0xd6, 0x47, 0x35, 0xa4, 0xd1, 0x40, 0x32, 0xa3,
	0xc4, 0x55, 0x27, 0xb6, 0xc3, 0x52, 0x20, 0xb1,
	0xca, 0x5b, 0x29, 0xb8, 0xcd, 0x5c, 0x2e, 0xbf,

	0x90, 0x01, 0x73, 0xe2, 0x97, 0x06, 0x74, 0xe5,
	0x9e, 0x0f, 0x7d, 0xec, 0x99, 0x08, 0x7a, 0xeb,
	0x8c, 0x1d, 0x6f, 0xfe, 0x8b, 0x1a, 0x68, 0xf9,
	0x82, 0x13, 0x61, 0xf0, 0x85, 0x14, 0x66, 0xf7,

	0xa8, 0x39, 0x4b, 0xda, 0xaf, 0x3e, 0x4c, 0xdd,
	0xa6, 0x37, 0x45, 0xd4, 0xa1, 0x30, 0x42, 0xd3,
	0xb4, 0x25, 0x57, 0xc6, 0xb3, 0x22, 0x50, 0xc1,
	0xba, 0x2b, 0x59, 0xc8, 0xbd, 0x2c, 0x5e, 0xcf
};

static uint8_t rfcomm_calc_fcs(uint16_t len, const uint8_t *data)
{
	uint8_t fcs = 0xff;

	while (len--) {
		fcs = rfcomm_crc_table[fcs ^ *data++];
	}

	/* Ones compliment */
	return (0xff - fcs);
}

static bool rfcomm_check_fcs(uint16_t len, const uint8_t *data,
			     uint8_t recvd_fcs)
{
	uint8_t fcs = 0xff;

	while (len--) {
		fcs = rfcomm_crc_table[fcs ^ *data++];
	}

	/* Ones compliment */
	fcs = rfcomm_crc_table[fcs ^ recvd_fcs];

	/*0xCF is the reversed order of 11110011.*/
	return (fcs == 0xcf);
}

static struct bt_rfcomm_dlc *rfcomm_dlcs_lookup_dlci(struct bt_rfcomm_dlc *dlcs,
						     uint8_t dlci)
{
	for (; dlcs; dlcs = dlcs->_next) {
		if (dlcs->dlci == dlci) {
			return dlcs;
		}
	}

	return NULL;
}

static struct bt_rfcomm_dlc *rfcomm_dlcs_remove_dlci(struct bt_rfcomm_dlc *dlcs,
						     uint8_t dlci)
{
	struct bt_rfcomm_dlc *tmp;

	if (!dlcs) {
		return NULL;
	}

	/* If first node is the one to be removed */
	if (dlcs->dlci == dlci) {
		dlcs->session->dlcs = dlcs->_next;
		return dlcs;
	}

	for (tmp = dlcs, dlcs = dlcs->_next; dlcs; dlcs = dlcs->_next) {
		if (dlcs->dlci == dlci) {
			tmp->_next = dlcs->_next;
			return dlcs;
		}
		tmp = dlcs;
	}

	return NULL;
}

static struct bt_rfcomm_server *rfcomm_server_lookup_channel(uint8_t channel)
{
	struct bt_rfcomm_server *server;

	for (server = servers; server; server = server->_next) {
		if (server->channel == channel) {
			return server;
		}
	}

	return NULL;
}

static struct bt_rfcomm_session *
rfcomm_sessions_lookup_bt_conn(struct bt_conn *conn)
{
	int i;

	for (i = 0; i < ARRAY_SIZE(bt_rfcomm_pool); i++) {
		struct bt_rfcomm_session *session = &bt_rfcomm_pool[i];

		if (session->br_chan.chan.conn == conn) {
			return session;
		}
	}

	return NULL;
}

int bt_rfcomm_server_register(struct bt_rfcomm_server *server)
{
	if (server->channel < RFCOMM_CHANNEL_START ||
	    server->channel > RFCOMM_CHANNEL_END || !server->accept) {
		return -EINVAL;
	}

	/* Check if given channel is already in use */
	if (rfcomm_server_lookup_channel(server->channel)) {
		BT_DBG("Channel already registered");
		return -EADDRINUSE;
	}

	BT_DBG("Channel 0x%02x", server->channel);

	server->_next = servers;
	servers = server;

	return 0;
}

static void rfcomm_dlc_tx_give_credits(struct bt_rfcomm_dlc *dlc,
				       uint8_t credits)
{
	BT_DBG("dlc %p credits %u", dlc, credits);

	while (credits--) {
		k_sem_give(&dlc->tx_credits);
	}

	BT_DBG("dlc %p updated credits %u", dlc,
	       k_sem_count_get(&dlc->tx_credits));
}

static void rfcomm_dlc_destroy(struct bt_rfcomm_dlc *dlc)
{
	BT_DBG("dlc %p", dlc);

	k_work_cancel_delayable(&dlc->rtx_work);
	dlc->state = BT_RFCOMM_STATE_IDLE;
	dlc->session = NULL;

	if (dlc->ops && dlc->ops->disconnected) {
		dlc->ops->disconnected(dlc);
	}
}

static void rfcomm_dlc_disconnect(struct bt_rfcomm_dlc *dlc)
{
	uint8_t old_state = dlc->state;

	BT_DBG("dlc %p", dlc);

	if (dlc->state == BT_RFCOMM_STATE_DISCONNECTED) {
		return;
	}

	dlc->state = BT_RFCOMM_STATE_DISCONNECTED;

	switch (old_state) {
	case BT_RFCOMM_STATE_CONNECTED:
		/* Queue a dummy buffer to wake up and stop the
		 * tx thread for states where it was running.
		 */
		net_buf_put(&dlc->tx_queue,
			    net_buf_alloc(&dummy_pool, K_NO_WAIT));

		/* There could be a writer waiting for credits so return a
		 * dummy credit to wake it up.
		 */
		rfcomm_dlc_tx_give_credits(dlc, 1);
		k_sem_give(&dlc->session->fc);
		break;
	default:
		rfcomm_dlc_destroy(dlc);
		break;
	}
}

static void rfcomm_session_disconnected(struct bt_rfcomm_session *session)
{
	struct bt_rfcomm_dlc *dlc;

	BT_DBG("Session %p", session);

	if (session->state == BT_RFCOMM_STATE_DISCONNECTED) {
		return;
	}

	for (dlc = session->dlcs; dlc;) {
		struct bt_rfcomm_dlc *next;

		/* prefetch since disconnected callback may cleanup */
		next = dlc->_next;
		dlc->_next = NULL;

		rfcomm_dlc_disconnect(dlc);

		dlc = next;
	}

	session->state = BT_RFCOMM_STATE_DISCONNECTED;
	session->dlcs = NULL;
}

struct net_buf *bt_rfcomm_create_pdu(struct net_buf_pool *pool)
{
	/* Length in RFCOMM header can be 2 bytes depending on length of user
	 * data
	 */
	return bt_conn_create_pdu(pool,
				  sizeof(struct bt_l2cap_hdr) +
				  sizeof(struct bt_rfcomm_hdr) + 1);
}

static int rfcomm_send(struct bt_rfcomm_session *session, struct net_buf *buf)
{
	int err;

	err = bt_l2cap_chan_send(&session->br_chan.chan, buf);
	if (err < 0) {
		net_buf_unref(buf);
	}

	return err;
}

static int rfcomm_send_sabm(struct bt_rfcomm_session *session, uint8_t dlci)
{
	struct bt_rfcomm_hdr *hdr;
	struct net_buf *buf;
	uint8_t cr, fcs;

	buf = bt_l2cap_create_pdu(NULL, 0);

	hdr = net_buf_add(buf, sizeof(*hdr));
	cr = BT_RFCOMM_CMD_CR(session->role);
	hdr->address = BT_RFCOMM_SET_ADDR(dlci, cr);
	hdr->control = BT_RFCOMM_SET_CTRL(BT_RFCOMM_SABM, BT_RFCOMM_PF_NON_UIH);
	hdr->length = BT_RFCOMM_SET_LEN_8(0);

	fcs = rfcomm_calc_fcs(BT_RFCOMM_FCS_LEN_NON_UIH, buf->data);
	net_buf_add_u8(buf, fcs);

	return rfcomm_send(session, buf);
}

static int rfcomm_send_disc(struct bt_rfcomm_session *session, uint8_t dlci)
{
	struct bt_rfcomm_hdr *hdr;
	struct net_buf *buf;
	uint8_t fcs, cr;

	BT_DBG("dlci %d", dlci);

	buf = bt_l2cap_create_pdu(NULL, 0);

	hdr = net_buf_add(buf, sizeof(*hdr));
	cr = BT_RFCOMM_RESP_CR(session->role);
	hdr->address = BT_RFCOMM_SET_ADDR(dlci, cr);
	hdr->control = BT_RFCOMM_SET_CTRL(BT_RFCOMM_DISC, BT_RFCOMM_PF_NON_UIH);
	hdr->length = BT_RFCOMM_SET_LEN_8(0);
	fcs = rfcomm_calc_fcs(BT_RFCOMM_FCS_LEN_NON_UIH, buf->data);
	net_buf_add_u8(buf, fcs);

	return rfcomm_send(session, buf);
}

static void rfcomm_session_disconnect(struct bt_rfcomm_session *session)
{
	if (session->dlcs) {
		return;
	}

	session->state = BT_RFCOMM_STATE_DISCONNECTING;
	rfcomm_send_disc(session, 0);
	k_work_reschedule(&session->rtx_work, RFCOMM_DISC_TIMEOUT);
}

static struct net_buf *rfcomm_make_uih_msg(struct bt_rfcomm_session *session,
					   uint8_t cr, uint8_t type,
					   uint8_t len)
{
	struct bt_rfcomm_hdr *hdr;
	struct bt_rfcomm_msg_hdr *msg_hdr;
	struct net_buf *buf;
	uint8_t hdr_cr;

	buf = bt_l2cap_create_pdu(NULL, 0);

	hdr = net_buf_add(buf, sizeof(*hdr));
	hdr_cr = BT_RFCOMM_UIH_CR(session->role);
	hdr->address = BT_RFCOMM_SET_ADDR(0, hdr_cr);
	hdr->control = BT_RFCOMM_SET_CTRL(BT_RFCOMM_UIH, BT_RFCOMM_PF_UIH);
	hdr->length = BT_RFCOMM_SET_LEN_8(sizeof(*msg_hdr) + len);

	msg_hdr = net_buf_add(buf, sizeof(*msg_hdr));
	msg_hdr->type = BT_RFCOMM_SET_MSG_TYPE(type, cr);
	msg_hdr->len = BT_RFCOMM_SET_LEN_8(len);

	return buf;
}

static void rfcomm_connected(struct bt_l2cap_chan *chan)
{
	struct bt_rfcomm_session *session = RFCOMM_SESSION(chan);

	BT_DBG("Session %p", session);

	/* Need to include UIH header and FCS*/
	session->mtu = MIN(session->br_chan.rx.mtu,
			   session->br_chan.tx.mtu) -
			   BT_RFCOMM_HDR_SIZE + BT_RFCOMM_FCS_SIZE;

	if (session->state == BT_RFCOMM_STATE_CONNECTING) {
		rfcomm_send_sabm(session, 0);
	}
}

static void rfcomm_disconnected(struct bt_l2cap_chan *chan)
{
	struct bt_rfcomm_session *session = RFCOMM_SESSION(chan);

	BT_DBG("Session %p", session);

	k_work_cancel_delayable(&session->rtx_work);
	rfcomm_session_disconnected(session);
	session->state = BT_RFCOMM_STATE_IDLE;
}

static void rfcomm_dlc_rtx_timeout(struct k_work *work)
{
	struct bt_rfcomm_dlc *dlc = DLC_RTX(work);
	struct bt_rfcomm_session *session = dlc->session;

	BT_WARN("dlc %p state %d timeout", dlc, dlc->state);

	rfcomm_dlcs_remove_dlci(session->dlcs, dlc->dlci);
	rfcomm_dlc_disconnect(dlc);
	rfcomm_session_disconnect(session);
}

static void rfcomm_dlc_init(struct bt_rfcomm_dlc *dlc,
			    struct bt_rfcomm_session *session,
			    uint8_t dlci,
			    bt_rfcomm_role_t role)
{
	BT_DBG("dlc %p", dlc);

	dlc->dlci = dlci;
	dlc->session = session;
	dlc->rx_credit = RFCOMM_DEFAULT_CREDIT;
	dlc->state = BT_RFCOMM_STATE_INIT;
	dlc->role = role;
	k_work_init_delayable(&dlc->rtx_work, rfcomm_dlc_rtx_timeout);

	/* Start a conn timer which includes auth as well */
	k_work_schedule(&dlc->rtx_work, RFCOMM_CONN_TIMEOUT);

	dlc->_next = session->dlcs;
	session->dlcs = dlc;
}

static struct bt_rfcomm_dlc *rfcomm_dlc_accept(struct bt_rfcomm_session *session,
					       uint8_t dlci)
{
	struct bt_rfcomm_server *server;
	struct bt_rfcomm_dlc *dlc;
	uint8_t channel;

	channel = BT_RFCOMM_GET_CHANNEL(dlci);
	server = rfcomm_server_lookup_channel(channel);
	if (!server) {
		BT_ERR("Server Channel not registered");
		return NULL;
	}

	if (server->accept(session->br_chan.chan.conn, &dlc) < 0) {
		BT_DBG("Incoming connection rejected");
		return NULL;
	}

	if (!BT_RFCOMM_CHECK_MTU(dlc->mtu)) {
		rfcomm_dlc_destroy(dlc);
		return NULL;
	}

	rfcomm_dlc_init(dlc, session, dlci, BT_RFCOMM_ROLE_ACCEPTOR);
	dlc->mtu = MIN(dlc->mtu, session->mtu);

	return dlc;
}

static int rfcomm_send_dm(struct bt_rfcomm_session *session, uint8_t dlci)
{
	struct bt_rfcomm_hdr *hdr;
	struct net_buf *buf;
	uint8_t fcs, cr;

	BT_DBG("dlci %d", dlci);

	buf = bt_l2cap_create_pdu(NULL, 0);

	hdr = net_buf_add(buf, sizeof(*hdr));
	cr = BT_RFCOMM_RESP_CR(session->role);
	hdr->address = BT_RFCOMM_SET_ADDR(dlci, cr);
	/* For DM PF bit is not relevant, we set it 1 */
	hdr->control = BT_RFCOMM_SET_CTRL(BT_RFCOMM_DM, BT_RFCOMM_PF_NON_UIH);
	hdr->length = BT_RFCOMM_SET_LEN_8(0);
	fcs = rfcomm_calc_fcs(BT_RFCOMM_FCS_LEN_NON_UIH, buf->data);
	net_buf_add_u8(buf, fcs);

	return rfcomm_send(session, buf);
}

static void rfcomm_check_fc(struct bt_rfcomm_dlc *dlc)
{
	BT_DBG("%p", dlc);

	BT_DBG("Wait for credits or MSC FC %p", dlc);
	/* Wait for credits or MSC FC */
	k_sem_take(&dlc->tx_credits, K_FOREVER);

	if (dlc->session->cfc == BT_RFCOMM_CFC_SUPPORTED) {
		return;
	}

	k_sem_take(&dlc->session->fc, K_FOREVER);

	/* Give the sems immediately so that sem will be available for all
	 * the bufs in the queue. It will be blocked only once all the bufs
	 * are sent (which will preempt this thread) and FCOFF / FC bit
	 * with 1, is received.
	 */
	k_sem_give(&dlc->session->fc);
	k_sem_give(&dlc->tx_credits);
}

static void rfcomm_dlc_tx_thread(void *p1, void *p2, void *p3)
{
	struct bt_rfcomm_dlc *dlc = p1;
	k_timeout_t timeout = K_FOREVER;
	struct net_buf *buf;

	BT_DBG("Started for dlc %p", dlc);

	while (dlc->state == BT_RFCOMM_STATE_CONNECTED ||
	       dlc->state == BT_RFCOMM_STATE_USER_DISCONNECT) {
		/* Get next packet for dlc */
		BT_DBG("Wait for buf %p", dlc);
		buf = net_buf_get(&dlc->tx_queue, timeout);
		/* If its dummy buffer or non user disconnect then break */
		if ((dlc->state != BT_RFCOMM_STATE_CONNECTED &&
		     dlc->state != BT_RFCOMM_STATE_USER_DISCONNECT) ||
		    !buf || !buf->len) {
			if (buf) {
				net_buf_unref(buf);
			}
			break;
		}

		rfcomm_check_fc(dlc);
		if (dlc->state != BT_RFCOMM_STATE_CONNECTED &&
		    dlc->state != BT_RFCOMM_STATE_USER_DISCONNECT) {
			net_buf_unref(buf);
			break;
		}

		if (rfcomm_send(dlc->session, buf) < 0) {
			/* This fails only if channel is disconnected */
			dlc->state = BT_RFCOMM_STATE_DISCONNECTED;
			break;
		}

		if (dlc->state == BT_RFCOMM_STATE_USER_DISCONNECT) {
			timeout = K_NO_WAIT;
		}
	}

	BT_DBG("dlc %p disconnected - cleaning up", dlc);

	/* Give back any allocated buffers */
	while ((buf = net_buf_get(&dlc->tx_queue, K_NO_WAIT))) {
		net_buf_unref(buf);
	}

	if (dlc->state == BT_RFCOMM_STATE_USER_DISCONNECT) {
		dlc->state = BT_RFCOMM_STATE_DISCONNECTING;
	}

	if (dlc->state == BT_RFCOMM_STATE_DISCONNECTING) {
		rfcomm_send_disc(dlc->session, dlc->dlci);
		k_work_reschedule(&dlc->rtx_work, RFCOMM_DISC_TIMEOUT);
	} else {
		rfcomm_dlc_destroy(dlc);
	}

	BT_DBG("dlc %p exiting", dlc);
}

static int rfcomm_send_ua(struct bt_rfcomm_session *session, uint8_t dlci)
{
	struct bt_rfcomm_hdr *hdr;
	struct net_buf *buf;
	uint8_t cr, fcs;

	buf = bt_l2cap_create_pdu(NULL, 0);

	hdr = net_buf_add(buf, sizeof(*hdr));
	cr = BT_RFCOMM_RESP_CR(session->role);
	hdr->address = BT_RFCOMM_SET_ADDR(dlci, cr);
	hdr->control = BT_RFCOMM_SET_CTRL(BT_RFCOMM_UA, BT_RFCOMM_PF_NON_UIH);
	hdr->length = BT_RFCOMM_SET_LEN_8(0);

	fcs = rfcomm_calc_fcs(BT_RFCOMM_FCS_LEN_NON_UIH, buf->data);
	net_buf_add_u8(buf, fcs);

	return rfcomm_send(session, buf);
}

static int rfcomm_send_msc(struct bt_rfcomm_dlc *dlc, uint8_t cr,
			   uint8_t v24_signal)
{
	struct bt_rfcomm_msc *msc;
	struct net_buf *buf;
	uint8_t fcs;

	buf = rfcomm_make_uih_msg(dlc->session, cr, BT_RFCOMM_MSC,
				  sizeof(*msc));

	msc = net_buf_add(buf, sizeof(*msc));
	/* cr bit should be always 1 in MSC */
	msc->dlci = BT_RFCOMM_SET_ADDR(dlc->dlci, 1);
	msc->v24_signal = v24_signal;

	fcs = rfcomm_calc_fcs(BT_RFCOMM_FCS_LEN_UIH, buf->data);
	net_buf_add_u8(buf, fcs);

	return rfcomm_send(dlc->session, buf);
}

static int rfcomm_send_rls(struct bt_rfcomm_dlc *dlc, uint8_t cr,
			   uint8_t line_status)
{
	struct bt_rfcomm_rls *rls;
	struct net_buf *buf;
	uint8_t fcs;

	buf = rfcomm_make_uih_msg(dlc->session, cr, BT_RFCOMM_RLS,
				  sizeof(*rls));

	rls = net_buf_add(buf, sizeof(*rls));
	/* cr bit should be always 1 in RLS */
	rls->dlci = BT_RFCOMM_SET_ADDR(dlc->dlci, 1);
	rls->line_status = line_status;

	fcs = rfcomm_calc_fcs(BT_RFCOMM_FCS_LEN_UIH, buf->data);
	net_buf_add_u8(buf, fcs);

	return rfcomm_send(dlc->session, buf);
}

static int rfcomm_send_rpn(struct bt_rfcomm_session *session, uint8_t cr,
			   struct bt_rfcomm_rpn *rpn)
{
	struct net_buf *buf;
	uint8_t fcs;

	buf = rfcomm_make_uih_msg(session, cr, BT_RFCOMM_RPN, sizeof(*rpn));

	net_buf_add_mem(buf, rpn, sizeof(*rpn));

	fcs = rfcomm_calc_fcs(BT_RFCOMM_FCS_LEN_UIH, buf->data);
	net_buf_add_u8(buf, fcs);

	return rfcomm_send(session, buf);
}

static int rfcomm_send_test(struct bt_rfcomm_session *session, uint8_t cr,
			    uint8_t *pattern, uint8_t len)
{
	struct net_buf *buf;
	uint8_t fcs;

	buf = rfcomm_make_uih_msg(session, cr, BT_RFCOMM_TEST, len);

	net_buf_add_mem(buf, pattern, len);

	fcs = rfcomm_calc_fcs(BT_RFCOMM_FCS_LEN_UIH, buf->data);
	net_buf_add_u8(buf, fcs);

	return rfcomm_send(session, buf);
}

static int rfcomm_send_nsc(struct bt_rfcomm_session *session, uint8_t cmd_type)
{
	struct net_buf *buf;
	uint8_t fcs;

	buf = rfcomm_make_uih_msg(session, BT_RFCOMM_MSG_RESP_CR,
				  BT_RFCOMM_NSC, sizeof(cmd_type));

	net_buf_add_u8(buf, cmd_type);

	fcs = rfcomm_calc_fcs(BT_RFCOMM_FCS_LEN_UIH, buf->data);
	net_buf_add_u8(buf, fcs);

	return rfcomm_send(session, buf);
}

static int rfcomm_send_fcon(struct bt_rfcomm_session *session, uint8_t cr)
{
	struct net_buf *buf;
	uint8_t fcs;

	buf = rfcomm_make_uih_msg(session, cr, BT_RFCOMM_FCON, 0);

	fcs = rfcomm_calc_fcs(BT_RFCOMM_FCS_LEN_UIH, buf->data);
	net_buf_add_u8(buf, fcs);

	return rfcomm_send(session, buf);
}

static int rfcomm_send_fcoff(struct bt_rfcomm_session *session, uint8_t cr)
{
	struct net_buf *buf;
	uint8_t fcs;

	buf = rfcomm_make_uih_msg(session, cr, BT_RFCOMM_FCOFF, 0);

	fcs = rfcomm_calc_fcs(BT_RFCOMM_FCS_LEN_UIH, buf->data);
	net_buf_add_u8(buf, fcs);

	return rfcomm_send(session, buf);
}

static void rfcomm_dlc_connected(struct bt_rfcomm_dlc *dlc)
{
	dlc->state = BT_RFCOMM_STATE_CONNECTED;

	rfcomm_send_msc(dlc, BT_RFCOMM_MSG_CMD_CR, BT_RFCOMM_DEFAULT_V24_SIG);

	if (dlc->session->cfc == BT_RFCOMM_CFC_UNKNOWN) {
		/* This means PN negotiation is not done for this session and
		 * can happen only for 1.0b device.
		 */
		dlc->session->cfc = BT_RFCOMM_CFC_NOT_SUPPORTED;
	}

	if (dlc->session->cfc == BT_RFCOMM_CFC_NOT_SUPPORTED) {
		BT_DBG("CFC not supported %p", dlc);
		rfcomm_send_fcon(dlc->session, BT_RFCOMM_MSG_CMD_CR);
		/* Use tx_credits as binary sem for MSC FC */
		k_sem_init(&dlc->tx_credits, 0, 1);
	}

	/* Cancel conn timer */
	k_work_cancel_delayable(&dlc->rtx_work);

	k_fifo_init(&dlc->tx_queue);
	k_thread_create(&dlc->tx_thread, dlc->stack,
			K_KERNEL_STACK_SIZEOF(dlc->stack),
			rfcomm_dlc_tx_thread, dlc, NULL, NULL, K_PRIO_COOP(7),
			0, K_NO_WAIT);
	k_thread_name_set(&dlc->tx_thread, "BT DLC");

	if (dlc->ops && dlc->ops->connected) {
		dlc->ops->connected(dlc);
	}
}

enum security_result {
	RFCOMM_SECURITY_PASSED,
	RFCOMM_SECURITY_REJECT,
	RFCOMM_SECURITY_PENDING
};

static enum security_result rfcomm_dlc_security(struct bt_rfcomm_dlc *dlc)
{
	struct bt_conn *conn = dlc->session->br_chan.chan.conn;

	BT_DBG("dlc %p", dlc);

	/* If current security level is greater than or equal to required
	 * security level  then return SUCCESS.
	 * For SSP devices the current security will be at least MEDIUM
	 * since L2CAP is enforcing it
	 */
	if (conn->sec_level >= dlc->required_sec_level) {
		return RFCOMM_SECURITY_PASSED;
	}

	if (!bt_conn_set_security(conn, dlc->required_sec_level)) {
		/* If Security elevation is initiated or in progress */
		return RFCOMM_SECURITY_PENDING;
	}

	/* Security request failed */
	return RFCOMM_SECURITY_REJECT;
}

static void rfcomm_dlc_drop(struct bt_rfcomm_dlc *dlc)
{
	BT_DBG("dlc %p", dlc);

	rfcomm_dlcs_remove_dlci(dlc->session->dlcs, dlc->dlci);
	rfcomm_dlc_destroy(dlc);
}

static int rfcomm_dlc_close(struct bt_rfcomm_dlc *dlc)
{
	BT_DBG("dlc %p", dlc);

	switch (dlc->state) {
	case BT_RFCOMM_STATE_SECURITY_PENDING:
		if (dlc->role == BT_RFCOMM_ROLE_ACCEPTOR) {
			rfcomm_send_dm(dlc->session, dlc->dlci);
		}
		__fallthrough;
	case BT_RFCOMM_STATE_INIT:
		rfcomm_dlc_drop(dlc);
		break;
	case BT_RFCOMM_STATE_CONNECTING:
	case BT_RFCOMM_STATE_CONFIG:
		dlc->state = BT_RFCOMM_STATE_DISCONNECTING;
		rfcomm_send_disc(dlc->session, dlc->dlci);
		k_work_reschedule(&dlc->rtx_work, RFCOMM_DISC_TIMEOUT);
		break;
	case BT_RFCOMM_STATE_CONNECTED:
		dlc->state = BT_RFCOMM_STATE_DISCONNECTING;

		/* Queue a dummy buffer to wake up and stop the
		 * tx thread.
		 */
		net_buf_put(&dlc->tx_queue,
			    net_buf_alloc(&dummy_pool, K_NO_WAIT));

		/* There could be a writer waiting for credits so return a
		 * dummy credit to wake it up.
		 */
		rfcomm_dlc_tx_give_credits(dlc, 1);
		break;
	case BT_RFCOMM_STATE_DISCONNECTING:
	case BT_RFCOMM_STATE_DISCONNECTED:
		break;
	case BT_RFCOMM_STATE_IDLE:
	default:
		return -EINVAL;
	}

	return 0;
}

static void rfcomm_handle_sabm(struct bt_rfcomm_session *session, uint8_t dlci)
{
	if (!dlci) {
		if (rfcomm_send_ua(session, dlci) < 0) {
			return;
		}

		session->state = BT_RFCOMM_STATE_CONNECTED;
	} else {
		struct bt_rfcomm_dlc *dlc;
		enum security_result result;

		dlc = rfcomm_dlcs_lookup_dlci(session->dlcs, dlci);
		if (!dlc) {
			dlc = rfcomm_dlc_accept(session, dlci);
			if (!dlc) {
				rfcomm_send_dm(session, dlci);
				return;
			}
		}

		result = rfcomm_dlc_security(dlc);
		switch (result) {
		case RFCOMM_SECURITY_PENDING:
			dlc->state = BT_RFCOMM_STATE_SECURITY_PENDING;
			return;
		case RFCOMM_SECURITY_PASSED:
			break;
		case RFCOMM_SECURITY_REJECT:
		default:
			rfcomm_send_dm(session, dlci);
			rfcomm_dlc_drop(dlc);
			return;
		}

		if (rfcomm_send_ua(session, dlci) < 0) {
			return;
		}

		/* Cancel idle timer if any */
		k_work_cancel_delayable(&session->rtx_work);

		rfcomm_dlc_connected(dlc);
	}
}

static int rfcomm_send_pn(struct bt_rfcomm_dlc *dlc, uint8_t cr)
{
	struct bt_rfcomm_pn *pn;
	struct net_buf *buf;
	uint8_t fcs;

	buf = rfcomm_make_uih_msg(dlc->session, cr, BT_RFCOMM_PN, sizeof(*pn));

	BT_DBG("mtu %x", dlc->mtu);

	pn = net_buf_add(buf, sizeof(*pn));
	pn->dlci = dlc->dlci;
	pn->mtu = sys_cpu_to_le16(dlc->mtu);
	if (dlc->state == BT_RFCOMM_STATE_CONFIG &&
	    (dlc->session->cfc == BT_RFCOMM_CFC_UNKNOWN ||
	     dlc->session->cfc == BT_RFCOMM_CFC_SUPPORTED)) {
		pn->credits = dlc->rx_credit;
		if (cr) {
			pn->flow_ctrl = BT_RFCOMM_PN_CFC_CMD;
		} else {
			pn->flow_ctrl = BT_RFCOMM_PN_CFC_RESP;
		}
	} else {
		/* If PN comes in already opened dlc or cfc not supported
		 * these should be 0
		 */
		pn->credits = 0U;
		pn->flow_ctrl = 0U;
	}
	pn->max_retrans = 0U;
	pn->ack_timer = 0U;
	pn->priority = 0U;

	fcs = rfcomm_calc_fcs(BT_RFCOMM_FCS_LEN_UIH, buf->data);
	net_buf_add_u8(buf, fcs);

	return rfcomm_send(dlc->session, buf);
}

static int rfcomm_send_credit(struct bt_rfcomm_dlc *dlc, uint8_t credits)
{
	struct bt_rfcomm_hdr *hdr;
	struct net_buf *buf;
	uint8_t fcs, cr;

	BT_DBG("Dlc %p credits %d", dlc, credits);

	buf = bt_l2cap_create_pdu(NULL, 0);

	hdr = net_buf_add(buf, sizeof(*hdr));
	cr = BT_RFCOMM_UIH_CR(dlc->session->role);
	hdr->address = BT_RFCOMM_SET_ADDR(dlc->dlci, cr);
	hdr->control = BT_RFCOMM_SET_CTRL(BT_RFCOMM_UIH,
					  BT_RFCOMM_PF_UIH_CREDIT);
	hdr->length = BT_RFCOMM_SET_LEN_8(0);
	net_buf_add_u8(buf, credits);
	fcs = rfcomm_calc_fcs(BT_RFCOMM_FCS_LEN_UIH, buf->data);
	net_buf_add_u8(buf, fcs);

	return rfcomm_send(dlc->session, buf);
}

static int rfcomm_dlc_start(struct bt_rfcomm_dlc *dlc)
{
	enum security_result result;

	BT_DBG("dlc %p", dlc);

	result = rfcomm_dlc_security(dlc);
	switch (result) {
	case RFCOMM_SECURITY_PASSED:
		dlc->mtu = MIN(dlc->mtu, dlc->session->mtu);
		dlc->state = BT_RFCOMM_STATE_CONFIG;
		rfcomm_send_pn(dlc, BT_RFCOMM_MSG_CMD_CR);
		break;
	case RFCOMM_SECURITY_PENDING:
		dlc->state = BT_RFCOMM_STATE_SECURITY_PENDING;
		break;
	case RFCOMM_SECURITY_REJECT:
	default:
		return -EIO;
	}

	return 0;
}

static void rfcomm_handle_ua(struct bt_rfcomm_session *session, uint8_t dlci)
{
	struct bt_rfcomm_dlc *dlc, *next;
	int err;

	if (!dlci) {
		switch (session->state) {
		case BT_RFCOMM_STATE_CONNECTING:
			session->state = BT_RFCOMM_STATE_CONNECTED;
			for (dlc = session->dlcs; dlc; dlc = next) {
				next = dlc->_next;
				if (dlc->role == BT_RFCOMM_ROLE_INITIATOR &&
				    dlc->state == BT_RFCOMM_STATE_INIT) {
					if (rfcomm_dlc_start(dlc) < 0) {
						rfcomm_dlc_drop(dlc);
					}
				}
			}
			/* Disconnect session if there is no dlcs left */
			rfcomm_session_disconnect(session);
			break;
		case BT_RFCOMM_STATE_DISCONNECTING:
			session->state = BT_RFCOMM_STATE_DISCONNECTED;
			/* Cancel disc timer */
			k_work_cancel_delayable(&session->rtx_work);
			err = bt_l2cap_chan_disconnect(&session->br_chan.chan);
			if (err < 0) {
				session->state = BT_RFCOMM_STATE_IDLE;
			}
			break;
		default:
			break;
		}
	} else {
		dlc = rfcomm_dlcs_lookup_dlci(session->dlcs, dlci);
		if (!dlc) {
			return;
		}

		switch (dlc->state) {
		case BT_RFCOMM_STATE_CONNECTING:
			rfcomm_dlc_connected(dlc);
			break;
		case BT_RFCOMM_STATE_DISCONNECTING:
			rfcomm_dlc_drop(dlc);
			rfcomm_session_disconnect(session);
			break;
		default:
			break;
		}
	}
}

static void rfcomm_handle_dm(struct bt_rfcomm_session *session, uint8_t dlci)
{
	struct bt_rfcomm_dlc *dlc;

	BT_DBG("dlci %d", dlci);

	dlc = rfcomm_dlcs_remove_dlci(session->dlcs, dlci);
	if (!dlc) {
		return;
	}

	rfcomm_dlc_disconnect(dlc);
	rfcomm_session_disconnect(session);
}

static void rfcomm_handle_msc(struct bt_rfcomm_session *session,
			      struct net_buf *buf, uint8_t cr)
{
	struct bt_rfcomm_msc *msc = (void *)buf->data;
	struct bt_rfcomm_dlc *dlc;
	uint8_t dlci = BT_RFCOMM_GET_DLCI(msc->dlci);

	BT_DBG("dlci %d", dlci);

	dlc = rfcomm_dlcs_lookup_dlci(session->dlcs, dlci);
	if (!dlc) {
		return;
	}

	if (cr == BT_RFCOMM_MSG_RESP_CR) {
		return;
	}

	if (dlc->session->cfc == BT_RFCOMM_CFC_NOT_SUPPORTED) {
		/* Only FC bit affects the flow on RFCOMM level */
		if (BT_RFCOMM_GET_FC(msc->v24_signal)) {
			/* If FC bit is 1 the device is unable to accept frames.
			 * Take the semaphore with timeout K_NO_WAIT so that
			 * dlc thread will be blocked when it tries sem_take
			 * before sending the data. K_NO_WAIT timeout will make
			 * sure that RX thread will not be blocked while taking
			 * the semaphore.
			 */
			k_sem_take(&dlc->tx_credits, K_NO_WAIT);
		} else {
			/* Give the sem so that it will unblock the waiting dlc
			 * thread in sem_take().
			 */
			k_sem_give(&dlc->tx_credits);
		}
	}

	rfcomm_send_msc(dlc, BT_RFCOMM_MSG_RESP_CR, msc->v24_signal);
}

static void rfcomm_handle_rls(struct bt_rfcomm_session *session,
			      struct net_buf *buf, uint8_t cr)
{
	struct bt_rfcomm_rls *rls = (void *)buf->data;
	uint8_t dlci = BT_RFCOMM_GET_DLCI(rls->dlci);
	struct bt_rfcomm_dlc *dlc;

	BT_DBG("dlci %d", dlci);

	if (!cr) {
		/* Ignore if its a response */
		return;
	}

	dlc = rfcomm_dlcs_lookup_dlci(session->dlcs, dlci);
	if (!dlc) {
		return;
	}

	/* As per the ETSI same line status has to returned in the response */
	rfcomm_send_rls(dlc, BT_RFCOMM_MSG_RESP_CR, rls->line_status);
}

static void rfcomm_handle_rpn(struct bt_rfcomm_session *session,
			      struct net_buf *buf, uint8_t cr)
{
	struct bt_rfcomm_rpn default_rpn, *rpn = (void *)buf->data;
	uint8_t dlci = BT_RFCOMM_GET_DLCI(rpn->dlci);
	uint8_t data_bits, stop_bits, parity_bits;
	/* Exclude fcs to get number of value bytes */
	uint8_t value_len = buf->len - 1;

	BT_DBG("dlci %d", dlci);

	if (!cr) {
		/* Ignore if its a response */
		return;
	}

	if (value_len == sizeof(*rpn)) {
		/* Accept all the values proposed by the sender */
		rpn->param_mask = sys_cpu_to_le16(BT_RFCOMM_RPN_PARAM_MASK_ALL);
		rfcomm_send_rpn(session, BT_RFCOMM_MSG_RESP_CR, rpn);
		return;
	}

	if (value_len != 1U) {
		return;
	}

	/* If only one value byte then current port settings has to be returned
	 * We will send default values
	 */
	default_rpn.dlci = BT_RFCOMM_SET_ADDR(dlci, 1);
	default_rpn.baud_rate = BT_RFCOMM_RPN_BAUD_RATE_9600;
	default_rpn.flow_control = BT_RFCOMM_RPN_FLOW_NONE;
	default_rpn.xoff_char = BT_RFCOMM_RPN_XOFF_CHAR;
	default_rpn.xon_char = BT_RFCOMM_RPN_XON_CHAR;
	data_bits = BT_RFCOMM_RPN_DATA_BITS_8;
	stop_bits = BT_RFCOMM_RPN_STOP_BITS_1;
	parity_bits = BT_RFCOMM_RPN_PARITY_NONE;
	default_rpn.line_settings = BT_RFCOMM_SET_LINE_SETTINGS(data_bits,
								stop_bits,
								parity_bits);
	default_rpn.param_mask = sys_cpu_to_le16(BT_RFCOMM_RPN_PARAM_MASK_ALL);

	rfcomm_send_rpn(session, BT_RFCOMM_MSG_RESP_CR, &default_rpn);
}

static void rfcomm_handle_pn(struct bt_rfcomm_session *session,
			     struct net_buf *buf, uint8_t cr)
{
	struct bt_rfcomm_pn *pn = (void *)buf->data;
	struct bt_rfcomm_dlc *dlc;

	dlc = rfcomm_dlcs_lookup_dlci(session->dlcs, pn->dlci);
	if (!dlc) {
		/*  Ignore if it is a response */
		if (!cr) {
			return;
		}

		if (!BT_RFCOMM_CHECK_MTU(pn->mtu)) {
			BT_ERR("Invalid mtu %d", pn->mtu);
			rfcomm_send_dm(session, pn->dlci);
			return;
		}

		dlc = rfcomm_dlc_accept(session, pn->dlci);
		if (!dlc) {
			rfcomm_send_dm(session, pn->dlci);
			return;
		}

		BT_DBG("Incoming connection accepted dlc %p", dlc);

		dlc->mtu = MIN(dlc->mtu, sys_le16_to_cpu(pn->mtu));

		if (pn->flow_ctrl == BT_RFCOMM_PN_CFC_CMD) {
			if (session->cfc == BT_RFCOMM_CFC_UNKNOWN) {
				session->cfc = BT_RFCOMM_CFC_SUPPORTED;
			}
			k_sem_init(&dlc->tx_credits, 0, K_SEM_MAX_LIMIT);
			rfcomm_dlc_tx_give_credits(dlc, pn->credits);
		} else {
			session->cfc = BT_RFCOMM_CFC_NOT_SUPPORTED;
		}

		dlc->state = BT_RFCOMM_STATE_CONFIG;
		rfcomm_send_pn(dlc, BT_RFCOMM_MSG_RESP_CR);
		/* Cancel idle timer if any */
		k_work_cancel_delayable(&session->rtx_work);
	} else {
		/* If its a command */
		if (cr) {
			if (!BT_RFCOMM_CHECK_MTU(pn->mtu)) {
				BT_ERR("Invalid mtu %d", pn->mtu);
				rfcomm_dlc_close(dlc);
				return;
			}
			dlc->mtu = MIN(dlc->mtu, sys_le16_to_cpu(pn->mtu));
			rfcomm_send_pn(dlc, BT_RFCOMM_MSG_RESP_CR);
		} else {
			if (dlc->state != BT_RFCOMM_STATE_CONFIG) {
				return;
			}

			dlc->mtu = MIN(dlc->mtu, sys_le16_to_cpu(pn->mtu));
			if (pn->flow_ctrl == BT_RFCOMM_PN_CFC_RESP) {
				if (session->cfc == BT_RFCOMM_CFC_UNKNOWN) {
					session->cfc = BT_RFCOMM_CFC_SUPPORTED;
				}
				k_sem_init(&dlc->tx_credits, 0, K_SEM_MAX_LIMIT);
				rfcomm_dlc_tx_give_credits(dlc, pn->credits);
			} else {
				session->cfc = BT_RFCOMM_CFC_NOT_SUPPORTED;
			}

			dlc->state = BT_RFCOMM_STATE_CONNECTING;
			rfcomm_send_sabm(session, dlc->dlci);
		}
	}
}

static void rfcomm_handle_disc(struct bt_rfcomm_session *session, uint8_t dlci)
{
	struct bt_rfcomm_dlc *dlc;

	BT_DBG("Dlci %d", dlci);

	if (dlci) {
		dlc = rfcomm_dlcs_remove_dlci(session->dlcs, dlci);
		if (!dlc) {
			rfcomm_send_dm(session, dlci);
			return;
		}

		rfcomm_send_ua(session, dlci);
		rfcomm_dlc_disconnect(dlc);

		if (!session->dlcs) {
			/* Start a session idle timer */
			k_work_reschedule(&dlc->session->rtx_work,
					  RFCOMM_IDLE_TIMEOUT);
		}
	} else {
		/* Cancel idle timer */
		k_work_cancel_delayable(&session->rtx_work);
		rfcomm_send_ua(session, 0);
		rfcomm_session_disconnected(session);
	}
}

static void rfcomm_handle_msg(struct bt_rfcomm_session *session,
			      struct net_buf *buf)
{
	struct bt_rfcomm_msg_hdr *hdr;
	uint8_t msg_type, len, cr;

	if (buf->len < sizeof(*hdr)) {
		BT_ERR("Too small RFCOMM message");
		return;
	}

	hdr = net_buf_pull_mem(buf, sizeof(*hdr));
	msg_type = BT_RFCOMM_GET_MSG_TYPE(hdr->type);
	cr = BT_RFCOMM_GET_MSG_CR(hdr->type);
	len = BT_RFCOMM_GET_LEN(hdr->len);

	BT_DBG("msg type %x cr %x", msg_type, cr);

	switch (msg_type) {
	case BT_RFCOMM_PN:
		rfcomm_handle_pn(session, buf, cr);
		break;
	case BT_RFCOMM_MSC:
		rfcomm_handle_msc(session, buf, cr);
		break;
	case BT_RFCOMM_RLS:
		rfcomm_handle_rls(session, buf, cr);
		break;
	case BT_RFCOMM_RPN:
		rfcomm_handle_rpn(session, buf, cr);
		break;
	case BT_RFCOMM_TEST:
		if (!cr) {
			break;
		}
		rfcomm_send_test(session, BT_RFCOMM_MSG_RESP_CR, buf->data,
				 buf->len - 1);
		break;
	case BT_RFCOMM_FCON:
		if (session->cfc == BT_RFCOMM_CFC_SUPPORTED) {
			BT_ERR("FCON received when CFC is supported ");
			return;
		}

		if (!cr) {
			break;
		}

		/* Give the sem so that it will unblock the waiting dlc threads
		 * of this session in sem_take().
		 */
		k_sem_give(&session->fc);
		rfcomm_send_fcon(session, BT_RFCOMM_MSG_RESP_CR);
		break;
	case BT_RFCOMM_FCOFF:
		if (session->cfc == BT_RFCOMM_CFC_SUPPORTED) {
			BT_ERR("FCOFF received when CFC is supported ");
			return;
		}

		if (!cr) {
			break;
		}

		/* Take the semaphore with timeout K_NO_WAIT so that all the
		 * dlc threads in this session will be blocked when it tries
		 * sem_take before sending the data. K_NO_WAIT timeout will
		 * make sure that RX thread will not be blocked while taking
		 * the semaphore.
		 */
		k_sem_take(&session->fc, K_NO_WAIT);
		rfcomm_send_fcoff(session, BT_RFCOMM_MSG_RESP_CR);
		break;
	default:
		BT_WARN("Unknown/Unsupported RFCOMM Msg type 0x%02x", msg_type);
		rfcomm_send_nsc(session, hdr->type);
		break;
	}
}

static void rfcomm_dlc_update_credits(struct bt_rfcomm_dlc *dlc)
{
	uint8_t credits;

	if (dlc->session->cfc == BT_RFCOMM_CFC_NOT_SUPPORTED) {
		return;
	}

	BT_DBG("dlc %p credits %u", dlc, dlc->rx_credit);

	/* Only give more credits if it went below the defined threshold */
	if (dlc->rx_credit > RFCOMM_CREDITS_THRESHOLD) {
		return;
	}

	/* Restore credits */
	credits = RFCOMM_MAX_CREDITS - dlc->rx_credit;
	dlc->rx_credit += credits;

	rfcomm_send_credit(dlc, credits);
}

static void rfcomm_handle_data(struct bt_rfcomm_session *session,
			       struct net_buf *buf, uint8_t dlci, uint8_t pf)

{
	struct bt_rfcomm_dlc *dlc;

	BT_DBG("dlci %d, pf %d", dlci, pf);

	dlc = rfcomm_dlcs_lookup_dlci(session->dlcs, dlci);
	if (!dlc) {
		BT_ERR("Data recvd in non existing DLC");
		rfcomm_send_dm(session, dlci);
		return;
	}

	BT_DBG("dlc %p rx credit %d", dlc, dlc->rx_credit);

	if (dlc->state != BT_RFCOMM_STATE_CONNECTED) {
		return;
	}

	if (pf == BT_RFCOMM_PF_UIH_CREDIT) {
		rfcomm_dlc_tx_give_credits(dlc, net_buf_pull_u8(buf));
	}

	if (buf->len > BT_RFCOMM_FCS_SIZE) {
		if (dlc->session->cfc == BT_RFCOMM_CFC_SUPPORTED &&
		    !dlc->rx_credit) {
			BT_ERR("Data recvd when rx credit is 0");
			rfcomm_dlc_close(dlc);
			return;
		}

		/* Remove FCS */
		buf->len -= BT_RFCOMM_FCS_SIZE;
		if (dlc->ops && dlc->ops->recv) {
			dlc->ops->recv(dlc, buf);
		}

		dlc->rx_credit--;
		rfcomm_dlc_update_credits(dlc);
	}
}

int bt_rfcomm_dlc_send(struct bt_rfcomm_dlc *dlc, struct net_buf *buf)
{
	uint8_t fcs, cr;

	if (!buf) {
		return -EINVAL;
	}

	BT_DBG("dlc %p tx credit %d", dlc, k_sem_count_get(&dlc->tx_credits));

	if (dlc->state != BT_RFCOMM_STATE_CONNECTED) {
		return -ENOTCONN;
	}

	if (buf->len > dlc->mtu) {
		return -EMSGSIZE;
	}

	/* length */
	if (buf->len > BT_RFCOMM_MAX_LEN_8) {
		/* Length is 2 byte */
		net_buf_push_le16(buf, BT_RFCOMM_SET_LEN_16(buf->len));
	} else {
		net_buf_push_u8(buf, BT_RFCOMM_SET_LEN_8(buf->len));
	}

	/* control */
	net_buf_push_u8(buf, BT_RFCOMM_SET_CTRL(BT_RFCOMM_UIH,
					BT_RFCOMM_PF_UIH_NO_CREDIT));
	/* address */
	cr = BT_RFCOMM_UIH_CR(dlc->session->role);
	net_buf_push_u8(buf, BT_RFCOMM_SET_ADDR(dlc->dlci, cr));

	fcs = rfcomm_calc_fcs(BT_RFCOMM_FCS_LEN_UIH, buf->data);
	net_buf_add_u8(buf, fcs);

	net_buf_put(&dlc->tx_queue, buf);

	return buf->len;
}

static int rfcomm_recv(struct bt_l2cap_chan *chan, struct net_buf *buf)
{
	struct bt_rfcomm_session *session = RFCOMM_SESSION(chan);
	struct bt_rfcomm_hdr *hdr = (void *)buf->data;
	uint8_t dlci, frame_type, fcs, fcs_len;

	/* Need to consider FCS also*/
	if (buf->len < (sizeof(*hdr) + 1)) {
		BT_ERR("Too small RFCOMM Frame");
		return 0;
	}

	dlci = BT_RFCOMM_GET_DLCI(hdr->address);
	frame_type = BT_RFCOMM_GET_FRAME_TYPE(hdr->control);

	BT_DBG("session %p dlci %x type %x", session, dlci, frame_type);

	fcs_len = (frame_type == BT_RFCOMM_UIH) ? BT_RFCOMM_FCS_LEN_UIH :
		   BT_RFCOMM_FCS_LEN_NON_UIH;
	fcs = *(net_buf_tail(buf) - 1);
	if (!rfcomm_check_fcs(fcs_len, buf->data, fcs)) {
		BT_ERR("FCS check failed");
		return 0;
	}

	if (BT_RFCOMM_LEN_EXTENDED(hdr->length)) {
		net_buf_pull(buf, sizeof(*hdr) + 1);
	} else {
		net_buf_pull(buf, sizeof(*hdr));
	}

	switch (frame_type) {
	case BT_RFCOMM_SABM:
		rfcomm_handle_sabm(session, dlci);
		break;
	case BT_RFCOMM_UIH:
		if (!dlci) {
			rfcomm_handle_msg(session, buf);
		} else {
			rfcomm_handle_data(session, buf, dlci,
					   BT_RFCOMM_GET_PF(hdr->control));
		}
		break;
	case BT_RFCOMM_DISC:
		rfcomm_handle_disc(session, dlci);
		break;
	case BT_RFCOMM_UA:
		rfcomm_handle_ua(session, dlci);
		break;
	case BT_RFCOMM_DM:
		rfcomm_handle_dm(session, dlci);
		break;
	default:
		BT_WARN("Unknown/Unsupported RFCOMM Frame type 0x%02x",
			frame_type);
		break;
	}

	return 0;
}

static void rfcomm_encrypt_change(struct bt_l2cap_chan *chan,
				  uint8_t hci_status)
{
	struct bt_rfcomm_session *session = RFCOMM_SESSION(chan);
	struct bt_conn *conn = chan->conn;
	struct bt_rfcomm_dlc *dlc, *next;

	BT_DBG("session %p status 0x%02x encr 0x%02x", session, hci_status,
	       conn->encrypt);

	for (dlc = session->dlcs; dlc; dlc = next) {
		next = dlc->_next;

		if (dlc->state != BT_RFCOMM_STATE_SECURITY_PENDING) {
			continue;
		}

		if (hci_status || !conn->encrypt ||
		    conn->sec_level < dlc->required_sec_level) {
			rfcomm_dlc_close(dlc);
			continue;
		}

		if (dlc->role == BT_RFCOMM_ROLE_ACCEPTOR) {
			rfcomm_send_ua(session, dlc->dlci);
			rfcomm_dlc_connected(dlc);
		} else {
			dlc->mtu = MIN(dlc->mtu, session->mtu);
			dlc->state = BT_RFCOMM_STATE_CONFIG;
			rfcomm_send_pn(dlc, BT_RFCOMM_MSG_CMD_CR);
		}
	}
}

static void rfcomm_session_rtx_timeout(struct k_work *work)
{
	struct bt_rfcomm_session *session = SESSION_RTX(work);

	BT_WARN("session %p state %d timeout", session, session->state);

	switch (session->state) {
	case BT_RFCOMM_STATE_CONNECTED:
		rfcomm_session_disconnect(session);
		break;
	case BT_RFCOMM_STATE_DISCONNECTING:
		session->state = BT_RFCOMM_STATE_DISCONNECTED;
		if (bt_l2cap_chan_disconnect(&session->br_chan.chan) < 0) {
			session->state = BT_RFCOMM_STATE_IDLE;
		}
		break;
	}
}

static struct bt_rfcomm_session *rfcomm_session_new(bt_rfcomm_role_t role)
{
	int i;
	static const struct bt_l2cap_chan_ops ops = {
		.connected = rfcomm_connected,
		.disconnected = rfcomm_disconnected,
		.recv = rfcomm_recv,
		.encrypt_change = rfcomm_encrypt_change,
	};

	for (i = 0; i < ARRAY_SIZE(bt_rfcomm_pool); i++) {
		struct bt_rfcomm_session *session = &bt_rfcomm_pool[i];

		if (session->br_chan.chan.conn) {
			continue;
		}

		BT_DBG("session %p initialized", session);

		session->br_chan.chan.ops = &ops;
		session->br_chan.rx.mtu	= CONFIG_BT_RFCOMM_L2CAP_MTU;
		session->state = BT_RFCOMM_STATE_INIT;
		session->role = role;
		session->cfc = BT_RFCOMM_CFC_UNKNOWN;
		k_work_init_delayable(&session->rtx_work,
				      rfcomm_session_rtx_timeout);
		k_sem_init(&session->fc, 0, 1);

		return session;
	}

	return NULL;
}

int bt_rfcomm_dlc_connect(struct bt_conn *conn, struct bt_rfcomm_dlc *dlc,
			  uint8_t channel)
{
	struct bt_rfcomm_session *session;
	struct bt_l2cap_chan *chan;
	uint8_t dlci;
	int ret;

	BT_DBG("conn %p dlc %p channel %d", conn, dlc, channel);

	if (!dlc) {
		return -EINVAL;
	}

	if (!conn || conn->state != BT_CONN_CONNECTED) {
		return -ENOTCONN;
	}

	if (channel < RFCOMM_CHANNEL_START || channel > RFCOMM_CHANNEL_END) {
		return -EINVAL;
	}

	if (!BT_RFCOMM_CHECK_MTU(dlc->mtu)) {
		return -EINVAL;
	}

	session = rfcomm_sessions_lookup_bt_conn(conn);
	if (!session) {
		session = rfcomm_session_new(BT_RFCOMM_ROLE_INITIATOR);
		if (!session) {
			return -ENOMEM;
		}
	}

	dlci = BT_RFCOMM_DLCI(session->role, channel);

	if (rfcomm_dlcs_lookup_dlci(session->dlcs, dlci)) {
		return -EBUSY;
	}

	rfcomm_dlc_init(dlc, session, dlci, BT_RFCOMM_ROLE_INITIATOR);

	switch (session->state) {
	case BT_RFCOMM_STATE_INIT:
		if (session->role == BT_RFCOMM_ROLE_ACCEPTOR) {
			/* There is an ongoing incoming conn */
			break;
		}
		chan = &session->br_chan.chan;
		BR_CHAN(chan)->required_sec_level = dlc->required_sec_level;
		ret = bt_l2cap_chan_connect(conn, chan, BT_L2CAP_PSM_RFCOMM);
		if (ret < 0) {
			session->state = BT_RFCOMM_STATE_IDLE;
			goto fail;
		}
		session->state = BT_RFCOMM_STATE_CONNECTING;
		break;
	case BT_RFCOMM_STATE_CONNECTING:
		break;
	case BT_RFCOMM_STATE_CONNECTED:
		ret = rfcomm_dlc_start(dlc);
		if (ret < 0) {
			goto fail;
		}
		/* Cancel idle timer if any */
		k_work_cancel_delayable(&session->rtx_work);
		break;
	default:
		BT_ERR("Invalid session state %d", session->state);
		ret = -EINVAL;
		goto fail;
	}

	return 0;

fail:
	rfcomm_dlcs_remove_dlci(session->dlcs, dlc->dlci);
	dlc->state = BT_RFCOMM_STATE_IDLE;
	dlc->session = NULL;
	return ret;
}

int bt_rfcomm_dlc_disconnect(struct bt_rfcomm_dlc *dlc)
{
	BT_DBG("dlc %p", dlc);

	if (!dlc) {
		return -EINVAL;
	}

	if (dlc->state == BT_RFCOMM_STATE_CONNECTED) {
		/* This is to handle user initiated disconnect to send pending
		 * bufs in the queue before disconnecting
		 * Queue a dummy buffer (in case if queue is empty) to wake up
		 * and stop the tx thread.
		 */
		dlc->state = BT_RFCOMM_STATE_USER_DISCONNECT;
		net_buf_put(&dlc->tx_queue,
			    net_buf_alloc(&dummy_pool, K_NO_WAIT));

		k_work_reschedule(&dlc->rtx_work, RFCOMM_DISC_TIMEOUT);

		return 0;
	}

	return rfcomm_dlc_close(dlc);
}

static int rfcomm_accept(struct bt_conn *conn, struct bt_l2cap_chan **chan)
{
	struct bt_rfcomm_session *session;

	BT_DBG("conn %p", conn);

	session = rfcomm_session_new(BT_RFCOMM_ROLE_ACCEPTOR);
	if (session) {
		*chan = &session->br_chan.chan;
		return 0;
	}

	BT_ERR("No available RFCOMM context for conn %p", conn);

	return -ENOMEM;
}

void bt_rfcomm_init(void)
{
	static struct bt_l2cap_server server = {
		.psm       = BT_L2CAP_PSM_RFCOMM,
		.accept    = rfcomm_accept,
		.sec_level = BT_SECURITY_L1,
	};

	bt_l2cap_br_server_register(&server);
}
