From: "Felipe F. Tonello" <eu@felipetonello.com>
To: linux-bluetooth@vger.kernel.org
Cc: linux-kernel@vger.kernel.org,
Marcel Holtmann <marcel@holtmann.org>,
Johan Hedberg <johan.hedberg@gmail.com>,
Luiz Augusto von Dentz <luiz.dentz@gmail.com>
Subject: [PATCH v5 BlueZ 3/4] Bluetooth: L2CAP: Add BT_LE_CONN_PARAM socket option
Date: Thu, 13 Apr 2017 13:22:02 +0100 [thread overview]
Message-ID: <20170413122203.4247-4-eu@felipetonello.com> (raw)
In-Reply-To: <20170413122203.4247-1-eu@felipetonello.com>
There is a need for certain LE profiles (MIDI for example) to change the
current connection's parameters. In order to do that, this patch
introduces a new BT_LE_CONN_PARAM socket option for SOL_BLUETOOTH
protocol which allow user-space l2cap sockets to update the current
connection.
It necessary to expose all the connection parameters to user-space
because user-space are exposed to those values anyway, via PPCP
characteristic or particular profile specification.
If ROLE is SLAVE, then it will send a L2CAP_CONN_PARAM_UPDATE_REQ
signaling command to the MASTER, triggering proper LE parameter update
procedure. The connection parameters update will only occur upon a
successful L2CAP_CONN_PARAM_UPDATE_RSP sent by the MASTER.
If ROLE is MASTER, then immediately update the connection parameters.
Once the connection parameters are effective, a MGMT_EV_NEW_CONN_PARAM
event with the store_hint set is sent to user-space so an application
can store the connection parameters for persistence reasons.
Signed-off-by: Felipe F. Tonello <eu@felipetonello.com>
---
include/net/bluetooth/bluetooth.h | 8 +++
net/bluetooth/l2cap_sock.c | 110 ++++++++++++++++++++++++++++++++++++++
2 files changed, 118 insertions(+)
diff --git a/include/net/bluetooth/bluetooth.h b/include/net/bluetooth/bluetooth.h
index 01487192f628..ce5b3abd3b27 100644
--- a/include/net/bluetooth/bluetooth.h
+++ b/include/net/bluetooth/bluetooth.h
@@ -122,6 +122,14 @@ struct bt_voice {
#define BT_SNDMTU 12
#define BT_RCVMTU 13
+#define BT_LE_CONN_PARAM 14
+struct bt_le_conn_param {
+ __u16 min_interval;
+ __u16 max_interval;
+ __u16 latency;
+ __u16 supervision_timeout;
+};
+
__printf(1, 2)
void bt_info(const char *fmt, ...);
__printf(1, 2)
diff --git a/net/bluetooth/l2cap_sock.c b/net/bluetooth/l2cap_sock.c
index 507b80d59dec..1e096bd9ddde 100644
--- a/net/bluetooth/l2cap_sock.c
+++ b/net/bluetooth/l2cap_sock.c
@@ -515,6 +515,47 @@ static int l2cap_sock_getsockopt(struct socket *sock, int level, int optname,
lock_sock(sk);
switch (optname) {
+ case BT_LE_CONN_PARAM: {
+ struct bt_le_conn_param conn_param;
+ struct hci_conn_params *params;
+ struct hci_conn *hcon;
+ struct hci_dev *hdev;
+
+ if (!chan->conn) {
+ err = -ENOTCONN;
+ break;
+ }
+
+ hcon = chan->conn->hcon;
+ hdev = hcon->hdev;
+ hci_dev_lock(hdev);
+
+ params = hci_conn_params_lookup(hdev, &hcon->dst,
+ hcon->dst_type);
+
+ memset(&conn_param, 0, sizeof(conn_param));
+
+ if (params) {
+ conn_param.min_interval = params->conn_min_interval;
+ conn_param.max_interval = params->conn_max_interval;
+ conn_param.latency = params->conn_latency;
+ conn_param.supervision_timeout =
+ params->supervision_timeout;
+ } else {
+ conn_param.min_interval = hdev->le_conn_min_interval;
+ conn_param.max_interval = hdev->le_conn_max_interval;
+ conn_param.latency = hdev->le_conn_latency;
+ conn_param.supervision_timeout = hdev->le_supv_timeout;
+ }
+
+ hci_dev_unlock(hdev);
+
+ len = min_t(unsigned int, len, sizeof(conn_param));
+ if (copy_to_user(optval, (char *)&conn_param, len))
+ err = -EFAULT;
+
+ break;
+ }
case BT_SECURITY:
if (chan->chan_type != L2CAP_CHAN_CONN_ORIENTED &&
chan->chan_type != L2CAP_CHAN_FIXED &&
@@ -762,6 +803,75 @@ static int l2cap_sock_setsockopt(struct socket *sock, int level, int optname,
lock_sock(sk);
switch (optname) {
+ case BT_LE_CONN_PARAM: {
+ struct bt_le_conn_param conn_param;
+ struct hci_conn_params *hci_param;
+ struct hci_conn *hcon;
+ struct hci_dev *hdev;
+
+ len = min_t(unsigned int, sizeof(conn_param), optlen);
+ if (copy_from_user((char *)&conn_param, optval, len)) {
+ err = -EFAULT;
+ break;
+ }
+
+ if (!chan->conn) {
+ err = -ENOTCONN;
+ break;
+ }
+
+ err = hci_check_conn_params(conn_param.min_interval,
+ conn_param.max_interval,
+ conn_param.latency,
+ conn_param.supervision_timeout);
+ if (err < 0) {
+ BT_ERR("Ignoring invalid connection parameters");
+ break;
+ }
+
+ hcon = chan->conn->hcon;
+ hdev = hcon->hdev;
+
+ hci_dev_lock(hdev);
+
+ /* we add new param in case it doesn't exist */
+ hci_param = hci_conn_params_add(hdev, &hcon->dst,
+ hcon->dst_type);
+ if (!hci_param) {
+ err = -ENOMEM;
+ BT_ERR("Failed to add connection parameters");
+ hci_dev_unlock(hcon->hdev);
+ break;
+ }
+
+ hci_dev_unlock(hdev);
+
+ /* Send a L2CAP connection parameters update request, if
+ * the host role is slave.
+ */
+ if (hcon->role == HCI_ROLE_SLAVE) {
+ l2cap_le_conn_update_req(chan->conn,
+ conn_param.min_interval,
+ conn_param.max_interval,
+ conn_param.latency,
+ conn_param.supervision_timeout);
+ } else {
+ /* this function also updates the hci_param value */
+ hci_le_conn_update(hcon, conn_param.min_interval,
+ conn_param.max_interval,
+ conn_param.latency,
+ conn_param.supervision_timeout);
+
+ /* don't set the `store' hint */
+ mgmt_new_conn_param(hdev, &hcon->dst, hcon->dst_type,
+ false, conn_param.min_interval,
+ conn_param.max_interval,
+ conn_param.latency,
+ conn_param.supervision_timeout);
+ }
+ break;
+ }
+
case BT_SECURITY:
if (chan->chan_type != L2CAP_CHAN_CONN_ORIENTED &&
chan->chan_type != L2CAP_CHAN_FIXED &&
--
2.12.2
next prev parent reply other threads:[~2017-04-13 12:22 UTC|newest]
Thread overview: 9+ messages / expand[flat|nested] mbox.gz Atom feed top
2017-04-13 12:21 [PATCH v5 BlueZ 0/4] Connection Update improvements Felipe F. Tonello
2017-04-13 12:22 ` [PATCH v5 BlueZ 1/4] Bluetooth: L2CAP: Refactor L2CAP_CONN_PARAM_UPDATE_REQ into a function Felipe F. Tonello
2017-04-13 12:22 ` [PATCH v5 BlueZ 2/4] Bluetooth: L2CAP: Add handler for Connection Parameter Update Response Felipe F. Tonello
2017-04-13 12:22 ` Felipe F. Tonello [this message]
2017-04-13 12:22 ` [PATCH v5 BlueZ 4/4] Bluetooth: Handle Slave Connection Interval Range AD Felipe F. Tonello
2017-04-13 18:24 ` Vinicius Costa Gomes
2017-04-13 18:40 ` Luiz Augusto von Dentz
2017-04-13 20:01 ` kbuild test robot
2017-04-13 22:04 ` kbuild test robot
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=20170413122203.4247-4-eu@felipetonello.com \
--to=eu@felipetonello.com \
--cc=johan.hedberg@gmail.com \
--cc=linux-bluetooth@vger.kernel.org \
--cc=linux-kernel@vger.kernel.org \
--cc=luiz.dentz@gmail.com \
--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.