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>
This commit is contained in:
Jaganath Kanakkassery 2016-12-15 20:59:36 +05:30 committed by Johan Hedberg
commit 0b1e6fb231
2 changed files with 52 additions and 0 deletions

View file

@ -580,6 +580,26 @@ static int rfcomm_send_msc(struct bt_rfcomm_dlc *dlc, uint8_t cr)
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_msc(struct bt_rfcomm_session *session,
}
}
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 @@ static void rfcomm_handle_msg(struct bt_rfcomm_session *session,
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;

View file

@ -77,6 +77,12 @@ struct bt_rfcomm_msc {
#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