mirror of https://lore.kernel.org/lkml/
 help / color / mirror / Atom feed
From: Vibhav Pant <vibhavp@gmail.com>
To: linux-bluetooth@vger.kernel.org
Cc: marcel@holtmann.org, johan.hedberg@gmail.com,
	linux-kernel@vger.kernel.org, Vibhav Pant <vibhavp@gmail.com>
Subject: [PATCH 1/1] Bluetooth: mgmt: Add command for getting device IO capabilities.
Date: Sun, 11 Feb 2024 03:52:26 +0530	[thread overview]
Message-ID: <20240210222226.890031-2-vibhavp@gmail.com> (raw)
In-Reply-To: <20240210222226.890031-1-vibhavp@gmail.com>

get_device_io_capability allows to get a connected device's IO
capabilities, including the authentication method (and MITM support)
requested, stored in the hci_conn for the device.

Signed-off-by: Vibhav Pant <vibhavp@gmail.com>
---
 include/net/bluetooth/mgmt.h | 19 ++++++++
 net/bluetooth/mgmt.c         | 89 ++++++++++++++++++++++++++++++++++++
 2 files changed, 108 insertions(+)

diff --git a/include/net/bluetooth/mgmt.h b/include/net/bluetooth/mgmt.h
index d382679efd2b..dba431baaef8 100644
--- a/include/net/bluetooth/mgmt.h
+++ b/include/net/bluetooth/mgmt.h
@@ -878,6 +878,25 @@ struct mgmt_cp_mesh_send_cancel {
 } __packed;
 #define MGMT_MESH_SEND_CANCEL_SIZE	1
 
+#define MGMT_OP_GET_DEVICE_IO_CAPABILITY         0x005B
+struct mgmt_cp_get_device_io_capability {
+	struct mgmt_addr_info addr;
+} __packed;
+#define MGMT_GET_DEVICE_IO_CAPABILITY_SIZE       MGMT_ADDR_INFO_SIZE
+struct mgmt_rp_get_device_io_capability {
+	struct mgmt_addr_info addr;
+	__u8 flags;
+} __packed;
+
+#define MGMT_DEVICE_IO_CAP_FLAG_IO_DISPLAY_ONLY       BIT(0)
+#define MGMT_DEVICE_IO_CAP_FLAG_IO_DISPLAY_YESNO      BIT(1)
+#define MGMT_DEVICE_IO_CAP_FLAG_IO_KEYBOARD_ONLY      BIT(2)
+#define MGMT_DEVICE_IO_CAP_FLAG_IO_NO_INPUT_OUTPUT    BIT(3)
+#define MGMT_DEVICE_IO_CAP_FLAG_AT_NO_BONDING         BIT(4)
+#define MGMT_DEVICE_IO_CAP_FLAG_AT_DEDICATED_BONDING  BIT(5)
+#define MGMT_DEVICE_IO_CAP_FLAG_AT_GENERAL_BONDING    BIT(6)
+#define MGMT_DEVICE_IO_CAP_FLAG_AT_MITM               BIT(7)
+
 #define MGMT_EV_CMD_COMPLETE		0x0001
 struct mgmt_ev_cmd_complete {
 	__le16	opcode;
diff --git a/net/bluetooth/mgmt.c b/net/bluetooth/mgmt.c
index 78ab562807d0..92b4317e60a1 100644
--- a/net/bluetooth/mgmt.c
+++ b/net/bluetooth/mgmt.c
@@ -28,6 +28,7 @@
 #include <asm/unaligned.h>
 
 #include <net/bluetooth/bluetooth.h>
+#include <net/bluetooth/hci.h>
 #include <net/bluetooth/hci_core.h>
 #include <net/bluetooth/hci_sock.h>
 #include <net/bluetooth/l2cap.h>
@@ -67,6 +68,7 @@ static const u16 mgmt_commands[] = {
 	MGMT_OP_PIN_CODE_REPLY,
 	MGMT_OP_PIN_CODE_NEG_REPLY,
 	MGMT_OP_SET_IO_CAPABILITY,
+	MGMT_OP_GET_DEVICE_IO_CAPABILITY,
 	MGMT_OP_PAIR_DEVICE,
 	MGMT_OP_CANCEL_PAIR_DEVICE,
 	MGMT_OP_UNPAIR_DEVICE,
@@ -3303,6 +3305,92 @@ static int set_io_capability(struct sock *sk, struct hci_dev *hdev, void *data,
 				 NULL, 0);
 }
 
+static int get_device_io_capability(struct sock *sk, struct hci_dev *hdev,
+				    void *data, u16 len)
+{
+	struct mgmt_cp_get_device_io_capability *cp = data;
+	struct mgmt_rp_get_device_io_capability rp;
+	struct hci_conn *conn;
+	int err = 0;
+
+	bt_dev_dbg(hdev, "sock %p", sk);
+
+	memset(&rp, 0, sizeof(rp));
+	bacpy(&rp.addr.bdaddr, &cp->addr.bdaddr);
+	rp.addr.type = cp->addr.type;
+
+	if (!bdaddr_type_is_valid(cp->addr.type))
+		return mgmt_cmd_complete(sk, hdev->id,
+					 MGMT_OP_GET_DEVICE_IO_CAPABILITY,
+					 MGMT_STATUS_INVALID_PARAMS, &rp,
+					 sizeof(rp));
+	hci_dev_lock(hdev);
+
+	if (!hdev_is_powered(hdev)) {
+		err = mgmt_cmd_complete(sk, hdev->id,
+					MGMT_OP_GET_DEVICE_IO_CAPABILITY,
+					MGMT_STATUS_NOT_POWERED, &rp,
+					sizeof(rp));
+		goto unlock;
+	}
+
+	if (cp->addr.type == BDADDR_BREDR)
+		conn = hci_conn_hash_lookup_ba(hdev, ACL_LINK,
+					       &cp->addr.bdaddr);
+	else
+		conn = hci_conn_hash_lookup_ba(hdev, LE_LINK, &cp->addr.bdaddr);
+
+	if (!conn) {
+		err = mgmt_cmd_complete(sk, hdev->id,
+					MGMT_OP_GET_DEVICE_IO_CAPABILITY,
+					MGMT_STATUS_NOT_CONNECTED, &rp,
+					sizeof(rp));
+		goto unlock;
+	}
+
+	switch (conn->remote_cap) {
+	case HCI_IO_DISPLAY_ONLY:
+		rp.flags |= MGMT_DEVICE_IO_CAP_FLAG_IO_DISPLAY_ONLY;
+		break;
+	case HCI_IO_DISPLAY_YESNO:
+		rp.flags |= MGMT_DEVICE_IO_CAP_FLAG_IO_DISPLAY_YESNO;
+		break;
+	case HCI_IO_KEYBOARD_ONLY:
+		rp.flags |= MGMT_DEVICE_IO_CAP_FLAG_IO_KEYBOARD_ONLY;
+		break;
+	case HCI_IO_NO_INPUT_OUTPUT:
+		rp.flags |= MGMT_DEVICE_IO_CAP_FLAG_IO_NO_INPUT_OUTPUT;
+		break;
+	}
+
+	switch (conn->remote_auth) {
+	case HCI_AT_NO_BONDING_MITM:
+		rp.flags |= MGMT_DEVICE_IO_CAP_FLAG_AT_MITM;
+		fallthrough;
+	case HCI_AT_NO_BONDING:
+		rp.flags |= MGMT_DEVICE_IO_CAP_FLAG_AT_NO_BONDING;
+		break;
+	case HCI_AT_DEDICATED_BONDING_MITM:
+		rp.flags |= MGMT_DEVICE_IO_CAP_FLAG_AT_MITM;
+		fallthrough;
+	case HCI_AT_DEDICATED_BONDING:
+		rp.flags |= MGMT_DEVICE_IO_CAP_FLAG_AT_DEDICATED_BONDING;
+		break;
+	case HCI_AT_GENERAL_BONDING_MITM:
+		rp.flags |= MGMT_DEVICE_IO_CAP_FLAG_AT_MITM;
+		fallthrough;
+	case HCI_AT_GENERAL_BONDING:
+		rp.flags |= MGMT_DEVICE_IO_CAP_FLAG_AT_GENERAL_BONDING;
+		break;
+	}
+
+	err = mgmt_cmd_complete(sk, hdev->id, MGMT_OP_GET_DEVICE_IO_CAPABILITY,
+				MGMT_STATUS_SUCCESS, &rp, sizeof(rp));
+unlock:
+	hci_dev_unlock(hdev);
+	return err;
+}
+
 static struct mgmt_pending_cmd *find_pairing(struct hci_conn *conn)
 {
 	struct hci_dev *hdev = conn->hdev;
@@ -9217,6 +9305,7 @@ static const struct hci_mgmt_handler mgmt_handlers[] = {
 	{ pin_code_reply,          MGMT_PIN_CODE_REPLY_SIZE },
 	{ pin_code_neg_reply,      MGMT_PIN_CODE_NEG_REPLY_SIZE },
 	{ set_io_capability,       MGMT_SET_IO_CAPABILITY_SIZE },
+	{ get_device_io_capability,MGMT_GET_DEVICE_IO_CAPABILITY_SIZE },
 	{ pair_device,             MGMT_PAIR_DEVICE_SIZE },
 	{ cancel_pair_device,      MGMT_CANCEL_PAIR_DEVICE_SIZE },
 	{ unpair_device,           MGMT_UNPAIR_DEVICE_SIZE },
-- 
2.43.0


  reply	other threads:[~2024-02-10 22:22 UTC|newest]

Thread overview: 3+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2024-02-10 22:22 [PATCH 0/1] " Vibhav Pant
2024-02-10 22:22 ` Vibhav Pant [this message]
2024-02-11 15:57 ` Luiz Augusto von Dentz

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20240210222226.890031-2-vibhavp@gmail.com \
    --to=vibhavp@gmail.com \
    --cc=johan.hedberg@gmail.com \
    --cc=linux-bluetooth@vger.kernel.org \
    --cc=linux-kernel@vger.kernel.org \
    --cc=marcel@holtmann.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox

all inboxes | Powered by JetHome®