All of lore.kernel.org
 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] Bluetooth: mgmt: Add command for getting device IO capabilities 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 an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.