Bluetooth: RFCOMM: Respond to RLS command
If remote sends RLS command then it should be responded with the
value received.
> ACL Data RX: Handle 256 flags 0x02 dlen 12
Channel: 64 len 8 [PSM 3 mode 0] {chan 0}
RFCOMM: Unnumbered Info with Header Check (UIH) (0xef)
Address: 0x03 cr 1 dlci 0x00
Control: 0xef poll/final 0
Length: 4
FCS: 0x70
MCC Message type: Remote Line Status CMD (0x14)
Length: 2
dlci 10 error: 5
< ACL Data TX: Handle 256 flags 0x00 dlen 12
Channel: 64 len 8 [PSM 3 mode 0] {chan 0}
RFCOMM: Unnumbered Info with Header Check (UIH) (0xef)
Address: 0x01 cr 0 dlci 0x00
Control: 0xef poll/final 0
Length: 4
FCS: 0xaa
MCC Message type: Remote Line Status RSP (0x14)
Length: 2
dlci 10 error: 5
Change-Id: Ib70e02aede2088bca748d1eb68bee9b1bc47a65d
Signed-off-by: Jaganath Kanakkassery <jaganathx.kanakkassery@intel.com>
diff --git a/subsys/bluetooth/host/rfcomm.c b/subsys/bluetooth/host/rfcomm.c
index 5795a65..594cfb1 100644
--- a/subsys/bluetooth/host/rfcomm.c
+++ b/subsys/bluetooth/host/rfcomm.c
@@ -580,6 +580,26 @@
return bt_l2cap_chan_send(&dlc->session->br_chan.chan, 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, 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 bt_l2cap_chan_send(&dlc->session->br_chan.chan, buf);
+}
+
static void rfcomm_dlc_connected(struct bt_rfcomm_dlc *dlc)
{
dlc->state = BT_RFCOMM_STATE_CONNECTED;
@@ -893,6 +913,29 @@
}
}
+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_pn(struct bt_rfcomm_session *session,
struct net_buf *buf, uint8_t cr)
{
@@ -989,6 +1032,9 @@
case BT_RFCOMM_MSC:
rfcomm_handle_msc(session, buf, cr);
break;
+ case BT_RFCOMM_RLS:
+ rfcomm_handle_rls(session, buf, cr);
+ break;
default:
BT_WARN("Unknown/Unsupported RFCOMM Msg type 0x%02x", msg_type);
break;
diff --git a/subsys/bluetooth/host/rfcomm_internal.h b/subsys/bluetooth/host/rfcomm_internal.h
index 9733f65..5f44946 100644
--- a/subsys/bluetooth/host/rfcomm_internal.h
+++ b/subsys/bluetooth/host/rfcomm_internal.h
@@ -77,6 +77,12 @@
#define BT_RFCOMM_DISC 0x43
#define BT_RFCOMM_DM 0x0f
+#define BT_RFCOMM_RLS 0x14
+struct bt_rfcomm_rls {
+ uint8_t dlci;
+ uint8_t line_status;
+} __packed;
+
/* DV = 1 IC = 0 RTR = 1 RTC = 1 FC = 0 EXT = 0 */
#define BT_RFCOMM_DEFAULT_V24_SIG 0x8d