2016-09-19 18:04:24

by Szymon Janc

[permalink] [raw]
Subject: [PATCH 1/5] Bluetooth: Refactor read_ext_controller_info handler

There is no need to allocate heap for reply only to copy stack data to
it. This also fix rp memory leak and missing hdev unlock if kmalloc
failed.

Signed-off-by: Szymon Janc <[email protected]>
---
net/bluetooth/mgmt.c | 36 ++++++++++++++++--------------------
1 file changed, 16 insertions(+), 20 deletions(-)

diff --git a/net/bluetooth/mgmt.c b/net/bluetooth/mgmt.c
index 54dd218..604c481 100644
--- a/net/bluetooth/mgmt.c
+++ b/net/bluetooth/mgmt.c
@@ -881,42 +881,38 @@ static inline u16 eir_append_data(u8 *eir, u16 eir_len, u8 type, u8 *data,
static int read_ext_controller_info(struct sock *sk, struct hci_dev *hdev,
void *data, u16 data_len)
{
- struct mgmt_rp_read_ext_info *rp;
- char buff[512];
+ char buf[512];
+ struct mgmt_rp_read_ext_info *rp = (void *)buf;
u16 eir_len = 0;
- u8 name_len;
+ size_t name_len;

BT_DBG("sock %p %s", sk, hdev->name);

+ memset(&buf, 0, sizeof(buf));
+
hci_dev_lock(hdev);

+ bacpy(&rp->bdaddr, &hdev->bdaddr);
+
+ rp->version = hdev->hci_ver;
+ rp->manufacturer = cpu_to_le16(hdev->manufacturer);
+
+ rp->supported_settings = cpu_to_le32(get_supported_settings(hdev));
+ rp->current_settings = cpu_to_le32(get_current_settings(hdev));
+
if (hci_dev_test_flag(hdev, HCI_BREDR_ENABLED))
- eir_len = eir_append_data(buff, eir_len,
- EIR_CLASS_OF_DEV,
+ eir_len = eir_append_data(rp->eir, eir_len, EIR_CLASS_OF_DEV,
hdev->dev_class, 3);

name_len = strlen(hdev->dev_name);
- eir_len = eir_append_data(buff, eir_len, EIR_NAME_COMPLETE,
+ eir_len = eir_append_data(rp->eir, eir_len, EIR_NAME_COMPLETE,
hdev->dev_name, name_len);

name_len = strlen(hdev->short_name);
- eir_len = eir_append_data(buff, eir_len, EIR_NAME_SHORT,
+ eir_len = eir_append_data(rp->eir, eir_len, EIR_NAME_SHORT,
hdev->short_name, name_len);

- rp = kzalloc(sizeof(*rp) + eir_len, GFP_KERNEL);
- if (!rp)
- return -ENOMEM;
-
rp->eir_len = cpu_to_le16(eir_len);
- memcpy(rp->eir, buff, eir_len);
-
- bacpy(&rp->bdaddr, &hdev->bdaddr);
-
- rp->version = hdev->hci_ver;
- rp->manufacturer = cpu_to_le16(hdev->manufacturer);
-
- rp->supported_settings = cpu_to_le32(get_supported_settings(hdev));
- rp->current_settings = cpu_to_le32(get_current_settings(hdev));

hci_dev_unlock(hdev);

--
2.7.4



2016-09-19 18:04:28

by Szymon Janc

[permalink] [raw]
Subject: [PATCH 5/5] Bluetooth: Fix missing ext info event when setting appearance

From: Michał Narajowski <[email protected]>

This patch adds missing event when setting appearance, just like
in the set local name command.

Signed-off-by: Michał Narajowski <[email protected]>
Signed-off-by: Szymon Janc <[email protected]>
---
net/bluetooth/mgmt.c | 2 ++
1 file changed, 2 insertions(+)

diff --git a/net/bluetooth/mgmt.c b/net/bluetooth/mgmt.c
index ce9a249..eeecb4f 100644
--- a/net/bluetooth/mgmt.c
+++ b/net/bluetooth/mgmt.c
@@ -3180,6 +3180,8 @@ static int set_appearance(struct sock *sk, struct hci_dev *hdev, void *data,

if (hci_dev_test_flag(hdev, HCI_LE_ADV))
adv_expire(hdev, MGMT_ADV_FLAG_APPEARANCE);
+
+ ext_info_changed(hdev, sk);
}

err = mgmt_cmd_complete(sk, hdev->id, MGMT_OP_SET_APPEARANCE, 0, NULL,
--
2.7.4


2016-09-19 18:04:27

by Szymon Janc

[permalink] [raw]
Subject: [PATCH 4/5] Bluetooth: Add supported data types to ext info changed event

From: Michał Narajowski <[email protected]>

This patch adds EIR data to extended info changed event.

Signed-off-by: Michał Narajowski <[email protected]>
Signed-off-by: Szymon Janc <[email protected]>
---
net/bluetooth/mgmt.c | 14 ++++++++++----
1 file changed, 10 insertions(+), 4 deletions(-)

diff --git a/net/bluetooth/mgmt.c b/net/bluetooth/mgmt.c
index 2c77c63..ce9a249 100644
--- a/net/bluetooth/mgmt.c
+++ b/net/bluetooth/mgmt.c
@@ -947,12 +947,18 @@ static int read_ext_controller_info(struct sock *sk, struct hci_dev *hdev,

static int ext_info_changed(struct hci_dev *hdev, struct sock *skip)
{
- struct mgmt_ev_ext_info_changed ev;
+ char buf[512];
+ struct mgmt_ev_ext_info_changed *ev = (void *)buf;
+ u16 eir_len;

- ev.eir_len = cpu_to_le16(0);
+ memset(buf, 0, sizeof(buf));
+
+ eir_len = append_eir_data_to_buf(hdev, ev->eir);
+ ev->eir_len = cpu_to_le16(eir_len);

- return mgmt_limited_event(MGMT_EV_EXT_INFO_CHANGED, hdev, &ev,
- sizeof(ev), HCI_MGMT_EXT_INFO_EVENTS, skip);
+ return mgmt_limited_event(MGMT_EV_EXT_INFO_CHANGED, hdev, ev,
+ sizeof(*ev) + eir_len,
+ HCI_MGMT_EXT_INFO_EVENTS, skip);
}

static int send_settings_rsp(struct sock *sk, u16 opcode, struct hci_dev *hdev)
--
2.7.4


2016-09-19 18:04:26

by Szymon Janc

[permalink] [raw]
Subject: [PATCH 3/5] Bluetooth: Add appearance to Read Ext Controller Info command

If LE is enabled appearance is added to EIR data.

Signed-off-by: Michał Narajowski <[email protected]>
Signed-off-by: Szymon Janc <[email protected]>
---
net/bluetooth/mgmt.c | 7 +++++++
1 file changed, 7 insertions(+)

diff --git a/net/bluetooth/mgmt.c b/net/bluetooth/mgmt.c
index 2b6fe10..2c77c63 100644
--- a/net/bluetooth/mgmt.c
+++ b/net/bluetooth/mgmt.c
@@ -887,6 +887,13 @@ static u16 append_eir_data_to_buf(struct hci_dev *hdev, u8 *eir)
eir_len = eir_append_data(eir, eir_len, EIR_CLASS_OF_DEV,
hdev->dev_class, 3);

+ if (hci_dev_test_flag(hdev, HCI_LE_ENABLED)) {
+ u16 appearance = cpu_to_le16(hdev->appearance);
+
+ eir_len = eir_append_data(eir, eir_len, EIR_APPEARANCE,
+ (u8 *)&appearance, 2);
+ }
+
name_len = strlen(hdev->dev_name);
eir_len = eir_append_data(eir, eir_len, EIR_NAME_COMPLETE,
hdev->dev_name, name_len);
--
2.7.4


2016-09-19 18:04:25

by Szymon Janc

[permalink] [raw]
Subject: [PATCH 2/5] Bluetooth: Factor appending EIR to separate helper

From: Michał Narajowski <[email protected]>

This will also be used for Extended Information Event handling.

Signed-off-by: Michał Narajowski <[email protected]>
Signed-off-by: Szymon Janc <[email protected]>
---
net/bluetooth/mgmt.c | 35 ++++++++++++++++++++++-------------
1 file changed, 22 insertions(+), 13 deletions(-)

diff --git a/net/bluetooth/mgmt.c b/net/bluetooth/mgmt.c
index 604c481..2b6fe10 100644
--- a/net/bluetooth/mgmt.c
+++ b/net/bluetooth/mgmt.c
@@ -878,13 +878,32 @@ static inline u16 eir_append_data(u8 *eir, u16 eir_len, u8 type, u8 *data,
return eir_len;
}

+static u16 append_eir_data_to_buf(struct hci_dev *hdev, u8 *eir)
+{
+ u16 eir_len = 0;
+ size_t name_len;
+
+ if (hci_dev_test_flag(hdev, HCI_BREDR_ENABLED))
+ eir_len = eir_append_data(eir, eir_len, EIR_CLASS_OF_DEV,
+ hdev->dev_class, 3);
+
+ name_len = strlen(hdev->dev_name);
+ eir_len = eir_append_data(eir, eir_len, EIR_NAME_COMPLETE,
+ hdev->dev_name, name_len);
+
+ name_len = strlen(hdev->short_name);
+ eir_len = eir_append_data(eir, eir_len, EIR_NAME_SHORT,
+ hdev->short_name, name_len);
+
+ return eir_len;
+}
+
static int read_ext_controller_info(struct sock *sk, struct hci_dev *hdev,
void *data, u16 data_len)
{
char buf[512];
struct mgmt_rp_read_ext_info *rp = (void *)buf;
- u16 eir_len = 0;
- size_t name_len;
+ u16 eir_len;

BT_DBG("sock %p %s", sk, hdev->name);

@@ -900,18 +919,8 @@ static int read_ext_controller_info(struct sock *sk, struct hci_dev *hdev,
rp->supported_settings = cpu_to_le32(get_supported_settings(hdev));
rp->current_settings = cpu_to_le32(get_current_settings(hdev));

- if (hci_dev_test_flag(hdev, HCI_BREDR_ENABLED))
- eir_len = eir_append_data(rp->eir, eir_len, EIR_CLASS_OF_DEV,
- hdev->dev_class, 3);
-
- name_len = strlen(hdev->dev_name);
- eir_len = eir_append_data(rp->eir, eir_len, EIR_NAME_COMPLETE,
- hdev->dev_name, name_len);
-
- name_len = strlen(hdev->short_name);
- eir_len = eir_append_data(rp->eir, eir_len, EIR_NAME_SHORT,
- hdev->short_name, name_len);

+ eir_len = append_eir_data_to_buf(hdev, rp->eir);
rp->eir_len = cpu_to_le16(eir_len);

hci_dev_unlock(hdev);
--
2.7.4