aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorAndre Guedes <andre.guedes@openbossa.org>2014-07-01 17:10:11 -0400
committerMarcel Holtmann <marcel@holtmann.org>2014-07-03 11:42:55 -0400
commitffb5a827d5ca5aef3f3fe5d64e42f3cf7fed4fc8 (patch)
tree110209210a236f8d7bda497c7d42f7ca4d18b10d
parent662bc2e63de765bb701e3d3eca6af9fe553d72ac (diff)
Bluetooth: Introduce "New Connection Parameter" Event
This patch introduces a new Mgmt event called "New Connection Parameter". This event indicates to userspace the connection parameters values the remote device requested. The user may store these values and load them into kernel. This way, next time a connection is established to that device, the kernel will use those parameters values instead of the default ones. This event is sent when the remote device requests new connection parameters through connection parameter update procedure. This event is not sent for slave connections. Signed-off-by: Andre Guedes <andre.guedes@openbossa.org> Signed-off-by: Marcel Holtmann <marcel@holtmann.org>
-rw-r--r--include/net/bluetooth/hci_core.h3
-rw-r--r--include/net/bluetooth/mgmt.h10
-rw-r--r--net/bluetooth/hci_event.c4
-rw-r--r--net/bluetooth/l2cap_core.c6
-rw-r--r--net/bluetooth/mgmt.c19
5 files changed, 41 insertions, 1 deletions
diff --git a/include/net/bluetooth/hci_core.h b/include/net/bluetooth/hci_core.h
index 3404f9bd2da0..01fbbe20defb 100644
--- a/include/net/bluetooth/hci_core.h
+++ b/include/net/bluetooth/hci_core.h
@@ -1329,6 +1329,9 @@ void mgmt_new_ltk(struct hci_dev *hdev, struct smp_ltk *key, bool persistent);
1329void mgmt_new_irk(struct hci_dev *hdev, struct smp_irk *irk); 1329void mgmt_new_irk(struct hci_dev *hdev, struct smp_irk *irk);
1330void mgmt_new_csrk(struct hci_dev *hdev, struct smp_csrk *csrk, 1330void mgmt_new_csrk(struct hci_dev *hdev, struct smp_csrk *csrk,
1331 bool persistent); 1331 bool persistent);
1332void mgmt_new_conn_param(struct hci_dev *hdev, bdaddr_t *bdaddr,
1333 u8 bdaddr_type, u16 min_interval, u16 max_interval,
1334 u16 latency, u16 timeout);
1332void mgmt_reenable_advertising(struct hci_dev *hdev); 1335void mgmt_reenable_advertising(struct hci_dev *hdev);
1333void mgmt_smp_complete(struct hci_conn *conn, bool complete); 1336void mgmt_smp_complete(struct hci_conn *conn, bool complete);
1334 1337
diff --git a/include/net/bluetooth/mgmt.h b/include/net/bluetooth/mgmt.h
index 2d88f361a016..3c0f29614d1b 100644
--- a/include/net/bluetooth/mgmt.h
+++ b/include/net/bluetooth/mgmt.h
@@ -615,3 +615,13 @@ struct mgmt_ev_device_added {
615struct mgmt_ev_device_removed { 615struct mgmt_ev_device_removed {
616 struct mgmt_addr_info addr; 616 struct mgmt_addr_info addr;
617} __packed; 617} __packed;
618
619#define MGMT_EV_NEW_CONN_PARAM 0x001c
620struct mgmt_ev_new_conn_param {
621 struct mgmt_addr_info addr;
622 __u8 store_hint;
623 __le16 min_interval;
624 __le16 max_interval;
625 __le16 latency;
626 __le16 timeout;
627} __packed;
diff --git a/net/bluetooth/hci_event.c b/net/bluetooth/hci_event.c
index 544e2ef85d82..b9d16e0ed661 100644
--- a/net/bluetooth/hci_event.c
+++ b/net/bluetooth/hci_event.c
@@ -4417,6 +4417,10 @@ static void hci_le_remote_conn_param_req_evt(struct hci_dev *hdev,
4417 return send_conn_param_neg_reply(hdev, handle, 4417 return send_conn_param_neg_reply(hdev, handle,
4418 HCI_ERROR_INVALID_LL_PARAMS); 4418 HCI_ERROR_INVALID_LL_PARAMS);
4419 4419
4420 if (test_bit(HCI_CONN_MASTER, &hcon->flags))
4421 mgmt_new_conn_param(hdev, &hcon->dst, hcon->dst_type, min, max,
4422 latency, timeout);
4423
4420 cp.handle = ev->handle; 4424 cp.handle = ev->handle;
4421 cp.interval_min = ev->interval_min; 4425 cp.interval_min = ev->interval_min;
4422 cp.interval_max = ev->interval_max; 4426 cp.interval_max = ev->interval_max;
diff --git a/net/bluetooth/l2cap_core.c b/net/bluetooth/l2cap_core.c
index e203a5fdf874..058b3b2b59b5 100644
--- a/net/bluetooth/l2cap_core.c
+++ b/net/bluetooth/l2cap_core.c
@@ -5249,8 +5249,12 @@ static inline int l2cap_conn_param_update_req(struct l2cap_conn *conn,
5249 l2cap_send_cmd(conn, cmd->ident, L2CAP_CONN_PARAM_UPDATE_RSP, 5249 l2cap_send_cmd(conn, cmd->ident, L2CAP_CONN_PARAM_UPDATE_RSP,
5250 sizeof(rsp), &rsp); 5250 sizeof(rsp), &rsp);
5251 5251
5252 if (!err) 5252 if (!err) {
5253 mgmt_new_conn_param(hcon->hdev, &hcon->dst, hcon->dst_type,
5254 min, max, latency, to_multiplier);
5255
5253 hci_le_conn_update(hcon, min, max, latency, to_multiplier); 5256 hci_le_conn_update(hcon, min, max, latency, to_multiplier);
5257 }
5254 5258
5255 return 0; 5259 return 0;
5256} 5260}
diff --git a/net/bluetooth/mgmt.c b/net/bluetooth/mgmt.c
index ba5e215a7561..93cfefa260d5 100644
--- a/net/bluetooth/mgmt.c
+++ b/net/bluetooth/mgmt.c
@@ -116,6 +116,7 @@ static const u16 mgmt_events[] = {
116 MGMT_EV_NEW_CSRK, 116 MGMT_EV_NEW_CSRK,
117 MGMT_EV_DEVICE_ADDED, 117 MGMT_EV_DEVICE_ADDED,
118 MGMT_EV_DEVICE_REMOVED, 118 MGMT_EV_DEVICE_REMOVED,
119 MGMT_EV_NEW_CONN_PARAM,
119}; 120};
120 121
121#define CACHE_TIMEOUT msecs_to_jiffies(2 * 1000) 122#define CACHE_TIMEOUT msecs_to_jiffies(2 * 1000)
@@ -5690,6 +5691,24 @@ void mgmt_new_csrk(struct hci_dev *hdev, struct smp_csrk *csrk,
5690 mgmt_event(MGMT_EV_NEW_CSRK, hdev, &ev, sizeof(ev), NULL); 5691 mgmt_event(MGMT_EV_NEW_CSRK, hdev, &ev, sizeof(ev), NULL);
5691} 5692}
5692 5693
5694void mgmt_new_conn_param(struct hci_dev *hdev, bdaddr_t *bdaddr,
5695 u8 bdaddr_type, u16 min_interval, u16 max_interval,
5696 u16 latency, u16 timeout)
5697{
5698 struct mgmt_ev_new_conn_param ev;
5699
5700 memset(&ev, 0, sizeof(ev));
5701 bacpy(&ev.addr.bdaddr, bdaddr);
5702 ev.addr.type = link_to_bdaddr(LE_LINK, bdaddr_type);
5703 ev.store_hint = 0x00;
5704 ev.min_interval = cpu_to_le16(min_interval);
5705 ev.max_interval = cpu_to_le16(max_interval);
5706 ev.latency = cpu_to_le16(latency);
5707 ev.timeout = cpu_to_le16(timeout);
5708
5709 mgmt_event(MGMT_EV_NEW_CONN_PARAM, hdev, &ev, sizeof(ev), NULL);
5710}
5711
5693static inline u16 eir_append_data(u8 *eir, u16 eir_len, u8 type, u8 *data, 5712static inline u16 eir_append_data(u8 *eir, u16 eir_len, u8 type, u8 *data,
5694 u8 data_len) 5713 u8 data_len)
5695{ 5714{