2012-01-10 21:20:48

by Andre Guedes

[permalink] [raw]
Subject: [PATCH v2 0/7] MGMT Start Discovery command LE-Only Support

Hi all,

This patch series is basically a rebased version of the previous
series.

Coming patch series:
* MGMT Stop Discovery command LE-Only support
* Interleaved discovery support to MGMT Discovery commands

BR,

Andre

Andre Guedes (7):
Bluetooth: Add 'eir_len' param to mgmt_device_found()
Bluetooth: Report LE devices
Bluetooth: LE scan should send Discovering events
Bluetooth: Add helper functions to send LE scan commands
Bluetooth: LE scan infrastructure
Bluetooth: Add hci_do_le_scan() to hci_core
Bluetooth: MGMT start discovery LE-Only support

include/net/bluetooth/hci.h | 1 +
include/net/bluetooth/hci_core.h | 18 ++++++-
net/bluetooth/hci_core.c | 106 ++++++++++++++++++++++++++++++++++++++
net/bluetooth/hci_event.c | 35 ++++++++++---
net/bluetooth/mgmt.c | 30 +++++++++--
5 files changed, 178 insertions(+), 12 deletions(-)

--
1.7.8.1



2012-01-16 10:36:12

by Johan Hedberg

[permalink] [raw]
Subject: Re: [PATCH v2 2/7] Bluetooth: Report LE devices

Hi Andre,

On Tue, Jan 10, 2012, Andre Guedes wrote:
> Devices found during LE scan should be reported to userspace through
> mgmt_device_found events.
>
> Signed-off-by: Andre Guedes <[email protected]>
> Acked-by: Marcel Holtmann <[email protected]>
> ---
> net/bluetooth/hci_event.c | 5 +++++
> 1 files changed, 5 insertions(+), 0 deletions(-)

Patches 1 and 2 have been applied to my bluetooth-next tree (they were
the only ones with Marcels ack and I need those as a base to update the
kernel side to match the latest mgmt-api.txt in user space).

Johan

2012-01-11 14:13:03

by Andre Guedes

[permalink] [raw]
Subject: Re: [PATCH v2 4/7] Bluetooth: Add helper functions to send LE scan commands

Hi Johan,

On Wed, Jan 11, 2012 at 10:52 AM, Johan Hedberg <[email protected]> wrote:
> Hi Andre,
>
> On Tue, Jan 10, 2012, Andre Guedes wrote:
>> This patch creates two helper functions to send LE Set Scan
>> Parameters and LE Set Scan Enable commands.
>>
>> Signed-off-by: Andre Guedes <[email protected]>
>> Acked-by: Marcel Holtmann <[email protected]>
>> ---
>> ?net/bluetooth/hci_core.c | ? 23 +++++++++++++++++++++++
>> ?1 files changed, 23 insertions(+), 0 deletions(-)
>>
>> diff --git a/net/bluetooth/hci_core.c b/net/bluetooth/hci_core.c
>> index 29bc1c6..0f8884f 100644
>> --- a/net/bluetooth/hci_core.c
>> +++ b/net/bluetooth/hci_core.c
>> @@ -89,6 +89,29 @@ static void hci_notify(struct hci_dev *hdev, int event)
>> ? ? ? atomic_notifier_call_chain(&hci_notifier, event, hdev);
>> ?}
>>
>> +static int send_le_scan_param_cmd(struct hci_dev *hdev, u8 type, u16 interval,
>> + ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? u16 window)
>> +{
>> + ? ? struct hci_cp_le_set_scan_param cp;
>> +
>> + ? ? memset(&cp, 0, sizeof(cp));
>> + ? ? cp.type = type;
>> + ? ? cp.interval = cpu_to_le16(interval);
>> + ? ? cp.window = cpu_to_le16(window);
>> +
>> + ? ? return hci_send_cmd(hdev, HCI_OP_LE_SET_SCAN_PARAM, sizeof(cp), &cp);
>> +}
>> +
>> +static int send_le_scan_enable_cmd(struct hci_dev *hdev, u8 enable)
>> +{
>> + ? ? struct hci_cp_le_set_scan_enable cp;
>> +
>> + ? ? memset(&cp, 0, sizeof(cp));
>> + ? ? cp.enable = enable;
>> +
>> + ? ? return hci_send_cmd(hdev, HCI_OP_LE_SET_SCAN_ENABLE, sizeof(cp), &cp);
>> +}
>> +
>> ?/* ---- HCI requests ---- */
>>
>> ?void hci_req_complete(struct hci_dev *hdev, __u16 cmd, int result)
>
> This patch generates the following compiler warnings:
>
> net/bluetooth/hci_core.c:92:12: warning: 'send_le_scan_param_cmd' defined but not used [-Wunused-function]
> net/bluetooth/hci_core.c:105:12: warning: 'send_le_scan_enable_cmd' defined but not used [-Wunused-function]
>
> I suppose the functions should only be introduced in a patch that also
> contains some users for them.

These functions are used by the next patch (5/7).

The 5/7 patch is complex so I split this up to keep things easier
to review. If you guys still think it would be better to merge this
patch into 5/7, I do it.

Andre

2012-01-11 13:52:42

by Johan Hedberg

[permalink] [raw]
Subject: Re: [PATCH v2 4/7] Bluetooth: Add helper functions to send LE scan commands

Hi Andre,

On Tue, Jan 10, 2012, Andre Guedes wrote:
> This patch creates two helper functions to send LE Set Scan
> Parameters and LE Set Scan Enable commands.
>
> Signed-off-by: Andre Guedes <[email protected]>
> Acked-by: Marcel Holtmann <[email protected]>
> ---
> net/bluetooth/hci_core.c | 23 +++++++++++++++++++++++
> 1 files changed, 23 insertions(+), 0 deletions(-)
>
> diff --git a/net/bluetooth/hci_core.c b/net/bluetooth/hci_core.c
> index 29bc1c6..0f8884f 100644
> --- a/net/bluetooth/hci_core.c
> +++ b/net/bluetooth/hci_core.c
> @@ -89,6 +89,29 @@ static void hci_notify(struct hci_dev *hdev, int event)
> atomic_notifier_call_chain(&hci_notifier, event, hdev);
> }
>
> +static int send_le_scan_param_cmd(struct hci_dev *hdev, u8 type, u16 interval,
> + u16 window)
> +{
> + struct hci_cp_le_set_scan_param cp;
> +
> + memset(&cp, 0, sizeof(cp));
> + cp.type = type;
> + cp.interval = cpu_to_le16(interval);
> + cp.window = cpu_to_le16(window);
> +
> + return hci_send_cmd(hdev, HCI_OP_LE_SET_SCAN_PARAM, sizeof(cp), &cp);
> +}
> +
> +static int send_le_scan_enable_cmd(struct hci_dev *hdev, u8 enable)
> +{
> + struct hci_cp_le_set_scan_enable cp;
> +
> + memset(&cp, 0, sizeof(cp));
> + cp.enable = enable;
> +
> + return hci_send_cmd(hdev, HCI_OP_LE_SET_SCAN_ENABLE, sizeof(cp), &cp);
> +}
> +
> /* ---- HCI requests ---- */
>
> void hci_req_complete(struct hci_dev *hdev, __u16 cmd, int result)

This patch generates the following compiler warnings:

net/bluetooth/hci_core.c:92:12: warning: 'send_le_scan_param_cmd' defined but not used [-Wunused-function]
net/bluetooth/hci_core.c:105:12: warning: 'send_le_scan_enable_cmd' defined but not used [-Wunused-function]

I suppose the functions should only be introduced in a patch that also
contains some users for them.

Johan

2012-01-10 21:20:55

by Andre Guedes

[permalink] [raw]
Subject: [PATCH v2 7/7] Bluetooth: MGMT start discovery LE-Only support

This patch adds LE-Only discovery procedure support to MGMT Start
Discovery command.

Signed-off-by: Andre Guedes <[email protected]>
---
net/bluetooth/mgmt.c | 23 +++++++++++++++++++++--
1 files changed, 21 insertions(+), 2 deletions(-)

diff --git a/net/bluetooth/mgmt.c b/net/bluetooth/mgmt.c
index e7bbad8..05e6c1f 100644
--- a/net/bluetooth/mgmt.c
+++ b/net/bluetooth/mgmt.c
@@ -35,7 +35,16 @@
#define MGMT_VERSION 0
#define MGMT_REVISION 1

-#define INQUIRY_LEN_BREDR 0x08 /* TGAP(100) */
+/*
+ * These LE scan and inquiry parameters were chosen according to LE General
+ * Discovery Procedure specification.
+ */
+#define LE_SCAN_TYPE 0x01
+#define LE_SCAN_WIN 0x12
+#define LE_SCAN_INT 0x12
+#define LE_SCAN_TIMEOUT_LE_ONLY 10240 /* TGAP(gen_disc_scan_min) */
+
+#define INQUIRY_LEN_BREDR 0x08 /* TGAP(100) */

#define SERVICE_CACHE_TIMEOUT (5 * 1000)

@@ -1895,6 +1904,7 @@ static int start_discovery(struct sock *sk, u16 index,
unsigned char *data, u16 len)
{
struct mgmt_cp_start_discovery *cp = (void *) data;
+ unsigned long discov_type = cp->type;
struct pending_cmd *cmd;
struct hci_dev *hdev;
int err;
@@ -1930,7 +1940,16 @@ static int start_discovery(struct sock *sk, u16 index,
goto failed;
}

- err = hci_do_inquiry(hdev, INQUIRY_LEN_BREDR);
+ if (test_bit(MGMT_ADDR_BREDR, &discov_type))
+ err = hci_do_inquiry(hdev, INQUIRY_LEN_BREDR);
+ else if (test_bit(MGMT_ADDR_LE_PUBLIC, &discov_type) &&
+ test_bit(MGMT_ADDR_LE_RANDOM, &discov_type))
+ err = hci_do_le_scan(hdev, LE_SCAN_TYPE, LE_SCAN_INT,
+ LE_SCAN_WIN, LE_SCAN_TIMEOUT_LE_ONLY);
+ else
+ err = cmd_status(sk, index, MGMT_OP_START_DISCOVERY,
+ MGMT_STATUS_NOT_SUPPORTED);
+
if (err < 0)
mgmt_pending_remove(cmd);
else
--
1.7.8.1


2012-01-10 21:20:54

by Andre Guedes

[permalink] [raw]
Subject: [PATCH v2 6/7] Bluetooth: Add hci_do_le_scan() to hci_core

This patch adds to hci_core the hci_do_le_scan function which should
be used to scan LE devices.

Signed-off-by: Andre Guedes <[email protected]>
---
include/net/bluetooth/hci_core.h | 2 ++
net/bluetooth/hci_core.c | 21 +++++++++++++++++++++
2 files changed, 23 insertions(+), 0 deletions(-)

diff --git a/include/net/bluetooth/hci_core.h b/include/net/bluetooth/hci_core.h
index 07b9681..114d1a5 100644
--- a/include/net/bluetooth/hci_core.h
+++ b/include/net/bluetooth/hci_core.h
@@ -990,5 +990,7 @@ void hci_le_ltk_neg_reply(struct hci_conn *conn);

int hci_do_inquiry(struct hci_dev *hdev, u8 length);
int hci_cancel_inquiry(struct hci_dev *hdev);
+int hci_do_le_scan(struct hci_dev *hdev, u8 type, u16 interval, u16 window,
+ int timeout);

#endif /* __HCI_CORE_H */
diff --git a/net/bluetooth/hci_core.c b/net/bluetooth/hci_core.c
index 46bb069..a4f33eb 100644
--- a/net/bluetooth/hci_core.c
+++ b/net/bluetooth/hci_core.c
@@ -2798,5 +2798,26 @@ int hci_cancel_inquiry(struct hci_dev *hdev)
return hci_send_cmd(hdev, HCI_OP_INQUIRY_CANCEL, 0, NULL);
}

+int hci_do_le_scan(struct hci_dev *hdev, u8 type, u16 interval, u16 window,
+ int timeout)
+{
+ struct le_scan_params *params = &hdev->le_scan_params;
+
+ BT_DBG("%s", hdev->name);
+
+ if (work_busy(&hdev->le_scan_enable) ||
+ test_bit(HCI_LE_SCAN, &hdev->dev_flags))
+ return -EINPROGRESS;
+
+ params->type = type;
+ params->interval = interval;
+ params->window = window;
+ params->timeout = timeout;
+
+ queue_work(system_long_wq, &hdev->le_scan_enable);
+
+ return 0;
+}
+
module_param(enable_hs, bool, 0644);
MODULE_PARM_DESC(enable_hs, "Enable High Speed");
--
1.7.8.1


2012-01-10 21:20:53

by Andre Guedes

[permalink] [raw]
Subject: [PATCH v2 5/7] Bluetooth: LE scan infrastructure

This patch adds to hci_core an infrastructure to scan LE devices.

Two works were created to handle the LE scan. The le_scan_enable
work sends commands to the controller and waits for its results.
If the commands were executed successfully a delayed work
(le_scan_disable) is scheduled to disable the ongoing scanning
after some amount of time.

The le_scan_enable work should be queue on system_long_wq since
it can sleep for a few seconds in the worst case.

Signed-off-by: Andre Guedes <[email protected]>
---
include/net/bluetooth/hci.h | 1 +
include/net/bluetooth/hci_core.h | 13 ++++++++
net/bluetooth/hci_core.c | 61 ++++++++++++++++++++++++++++++++++++++
net/bluetooth/hci_event.c | 15 +++++++--
4 files changed, 87 insertions(+), 3 deletions(-)

diff --git a/include/net/bluetooth/hci.h b/include/net/bluetooth/hci.h
index 3ee39ed..5a45538 100644
--- a/include/net/bluetooth/hci.h
+++ b/include/net/bluetooth/hci.h
@@ -276,6 +276,7 @@ enum {

/* ---- HCI Error Codes ---- */
#define HCI_ERROR_AUTH_FAILURE 0x05
+#define HCI_ERROR_TIMEOUT 0x08
#define HCI_ERROR_REJ_BAD_ADDR 0x0f
#define HCI_ERROR_REMOTE_USER_TERM 0x13
#define HCI_ERROR_LOCAL_HOST_TERM 0x16
diff --git a/include/net/bluetooth/hci_core.h b/include/net/bluetooth/hci_core.h
index 954a577..07b9681 100644
--- a/include/net/bluetooth/hci_core.h
+++ b/include/net/bluetooth/hci_core.h
@@ -126,6 +126,13 @@ struct adv_entry {
u8 bdaddr_type;
};

+struct le_scan_params {
+ u8 type;
+ u16 interval;
+ u16 window;
+ int timeout;
+};
+
#define NUM_REASSEMBLY 4
struct hci_dev {
struct list_head list;
@@ -264,6 +271,12 @@ struct hci_dev {

unsigned long dev_flags;

+ struct work_struct le_scan_enable;
+ struct delayed_work le_scan_disable;
+ struct le_scan_params le_scan_params;
+ wait_queue_head_t le_scan_wait_q;
+ u8 le_scan_result;
+
int (*open)(struct hci_dev *hdev);
int (*close)(struct hci_dev *hdev);
int (*flush)(struct hci_dev *hdev);
diff --git a/net/bluetooth/hci_core.c b/net/bluetooth/hci_core.c
index 0f8884f..46bb069 100644
--- a/net/bluetooth/hci_core.c
+++ b/net/bluetooth/hci_core.c
@@ -778,6 +778,9 @@ static int hci_dev_do_close(struct hci_dev *hdev)
if (test_and_clear_bit(HCI_SERVICE_CACHE, &hdev->dev_flags))
cancel_delayed_work(&hdev->service_cache);

+ cancel_work_sync(&hdev->le_scan_enable);
+ cancel_delayed_work_sync(&hdev->le_scan_disable);
+
hci_dev_lock(hdev);
inquiry_cache_flush(hdev);
hci_conn_hash_flush(hdev);
@@ -1592,6 +1595,60 @@ int hci_add_adv_entry(struct hci_dev *hdev,
return 0;
}

+static void le_scan_enable_work(struct work_struct *work)
+{
+ struct hci_dev *hdev = container_of(work, struct hci_dev,
+ le_scan_enable);
+ struct le_scan_params *params = &hdev->le_scan_params;
+ long timeout = msecs_to_jiffies(3000);
+ DECLARE_WAITQUEUE(wait, current);
+
+ BT_DBG("%s", hdev->name);
+
+ add_wait_queue(&hdev->le_scan_wait_q, &wait);
+
+ /* Send LE Set Scan Parameter command and wait for the result */
+ hdev->le_scan_result = HCI_ERROR_TIMEOUT;
+ send_le_scan_param_cmd(hdev, params->type, params->interval,
+ params->window);
+
+ schedule_timeout_uninterruptible(timeout);
+ if (hdev->le_scan_result)
+ goto failed;
+
+ /* Send LE Set Scan Enable command and wait for the result */
+ hdev->le_scan_result = HCI_ERROR_TIMEOUT;
+ send_le_scan_enable_cmd(hdev, 1);
+
+ schedule_timeout_uninterruptible(timeout);
+ if (hdev->le_scan_result)
+ goto failed;
+
+ remove_wait_queue(&hdev->le_scan_wait_q, &wait);
+
+ schedule_delayed_work(&hdev->le_scan_disable,
+ msecs_to_jiffies(params->timeout));
+
+ return;
+
+failed:
+ remove_wait_queue(&hdev->le_scan_wait_q, &wait);
+
+ hci_dev_lock(hdev);
+ mgmt_start_discovery_failed(hdev, hdev->le_scan_result);
+ hci_dev_unlock(hdev);
+}
+
+static void le_scan_disable_work(struct work_struct *work)
+{
+ struct hci_dev *hdev = container_of(work, struct hci_dev,
+ le_scan_disable.work);
+
+ BT_DBG("%s", hdev->name);
+
+ send_le_scan_enable_cmd(hdev, 0);
+}
+
/* Register HCI device */
int hci_register_dev(struct hci_dev *hdev)
{
@@ -1677,6 +1734,10 @@ int hci_register_dev(struct hci_dev *hdev)

atomic_set(&hdev->promisc, 0);

+ INIT_WORK(&hdev->le_scan_enable, le_scan_enable_work);
+ INIT_DELAYED_WORK(&hdev->le_scan_disable, le_scan_disable_work);
+ init_waitqueue_head(&hdev->le_scan_wait_q);
+
write_unlock(&hci_dev_list_lock);

hdev->workqueue = alloc_workqueue(hdev->name, WQ_HIGHPRI | WQ_UNBOUND |
diff --git a/net/bluetooth/hci_event.c b/net/bluetooth/hci_event.c
index 2d86604..9ef2057 100644
--- a/net/bluetooth/hci_event.c
+++ b/net/bluetooth/hci_event.c
@@ -1024,6 +1024,9 @@ static void hci_cc_le_set_scan_param(struct hci_dev *hdev, struct sk_buff *skb)
__u8 status = *((__u8 *) skb->data);

BT_DBG("%s status 0x%x", hdev->name, status);
+
+ hdev->le_scan_result = status;
+ wake_up(&hdev->le_scan_wait_q);
}

static void hci_cc_le_set_scan_enable(struct hci_dev *hdev,
@@ -1034,15 +1037,18 @@ static void hci_cc_le_set_scan_enable(struct hci_dev *hdev,

BT_DBG("%s status 0x%x", hdev->name, status);

- if (status)
- return;
-
cp = hci_sent_cmd_data(hdev, HCI_OP_LE_SET_SCAN_ENABLE);
if (!cp)
return;

switch (cp->enable) {
case LE_SCANNING_ENABLED:
+ hdev->le_scan_result = status;
+ wake_up(&hdev->le_scan_wait_q);
+
+ if (status)
+ return;
+
set_bit(HCI_LE_SCAN, &hdev->dev_flags);

cancel_delayed_work_sync(&hdev->adv_work);
@@ -1054,6 +1060,9 @@ static void hci_cc_le_set_scan_enable(struct hci_dev *hdev,
break;

case LE_SCANNING_DISABLED:
+ if (status)
+ return;
+
clear_bit(HCI_LE_SCAN, &hdev->dev_flags);

hci_dev_lock(hdev);
--
1.7.8.1


2012-01-10 21:20:52

by Andre Guedes

[permalink] [raw]
Subject: [PATCH v2 4/7] Bluetooth: Add helper functions to send LE scan commands

This patch creates two helper functions to send LE Set Scan
Parameters and LE Set Scan Enable commands.

Signed-off-by: Andre Guedes <[email protected]>
Acked-by: Marcel Holtmann <[email protected]>
---
net/bluetooth/hci_core.c | 23 +++++++++++++++++++++++
1 files changed, 23 insertions(+), 0 deletions(-)

diff --git a/net/bluetooth/hci_core.c b/net/bluetooth/hci_core.c
index 29bc1c6..0f8884f 100644
--- a/net/bluetooth/hci_core.c
+++ b/net/bluetooth/hci_core.c
@@ -89,6 +89,29 @@ static void hci_notify(struct hci_dev *hdev, int event)
atomic_notifier_call_chain(&hci_notifier, event, hdev);
}

+static int send_le_scan_param_cmd(struct hci_dev *hdev, u8 type, u16 interval,
+ u16 window)
+{
+ struct hci_cp_le_set_scan_param cp;
+
+ memset(&cp, 0, sizeof(cp));
+ cp.type = type;
+ cp.interval = cpu_to_le16(interval);
+ cp.window = cpu_to_le16(window);
+
+ return hci_send_cmd(hdev, HCI_OP_LE_SET_SCAN_PARAM, sizeof(cp), &cp);
+}
+
+static int send_le_scan_enable_cmd(struct hci_dev *hdev, u8 enable)
+{
+ struct hci_cp_le_set_scan_enable cp;
+
+ memset(&cp, 0, sizeof(cp));
+ cp.enable = enable;
+
+ return hci_send_cmd(hdev, HCI_OP_LE_SET_SCAN_ENABLE, sizeof(cp), &cp);
+}
+
/* ---- HCI requests ---- */

void hci_req_complete(struct hci_dev *hdev, __u16 cmd, int result)
--
1.7.8.1


2012-01-10 21:20:51

by Andre Guedes

[permalink] [raw]
Subject: [PATCH v2 3/7] Bluetooth: LE scan should send Discovering events

Send MGMT Discovering events once LE scan starts/stops so the
userspace can track when local adapters are discovering LE devices.

This way, we also keep the same behavior of inquiry which sends MGMT
Discovering events once inquiry starts/stops even if it is triggered
by an external tool (e.g. hcitool).

Signed-off-by: Andre Guedes <[email protected]>
---
include/net/bluetooth/hci_core.h | 1 +
net/bluetooth/hci_core.c | 1 +
net/bluetooth/hci_event.c | 5 +++++
3 files changed, 7 insertions(+), 0 deletions(-)

diff --git a/include/net/bluetooth/hci_core.h b/include/net/bluetooth/hci_core.h
index 393acd0..954a577 100644
--- a/include/net/bluetooth/hci_core.h
+++ b/include/net/bluetooth/hci_core.h
@@ -61,6 +61,7 @@ struct discovery_state {
DISCOVERY_STOPPED,
DISCOVERY_STARTING,
DISCOVERY_INQUIRY,
+ DISCOVERY_LE_SCAN,
DISCOVERY_RESOLVING,
DISCOVERY_STOPPING,
} state;
diff --git a/net/bluetooth/hci_core.c b/net/bluetooth/hci_core.c
index ba2e725..29bc1c6 100644
--- a/net/bluetooth/hci_core.c
+++ b/net/bluetooth/hci_core.c
@@ -381,6 +381,7 @@ void hci_discovery_set_state(struct hci_dev *hdev, int state)
case DISCOVERY_STARTING:
break;
case DISCOVERY_INQUIRY:
+ case DISCOVERY_LE_SCAN:
mgmt_discovering(hdev, 1);
break;
case DISCOVERY_RESOLVING:
diff --git a/net/bluetooth/hci_event.c b/net/bluetooth/hci_event.c
index c2fe964..2d86604 100644
--- a/net/bluetooth/hci_event.c
+++ b/net/bluetooth/hci_event.c
@@ -1049,12 +1049,17 @@ static void hci_cc_le_set_scan_enable(struct hci_dev *hdev,

hci_dev_lock(hdev);
hci_adv_entries_clear(hdev);
+ hci_discovery_set_state(hdev, DISCOVERY_LE_SCAN);
hci_dev_unlock(hdev);
break;

case LE_SCANNING_DISABLED:
clear_bit(HCI_LE_SCAN, &hdev->dev_flags);

+ hci_dev_lock(hdev);
+ hci_discovery_set_state(hdev, DISCOVERY_STOPPED);
+ hci_dev_unlock(hdev);
+
schedule_delayed_work(&hdev->adv_work, ADV_CLEAR_TIMEOUT);
break;

--
1.7.8.1


2012-01-10 21:20:50

by Andre Guedes

[permalink] [raw]
Subject: [PATCH v2 2/7] Bluetooth: Report LE devices

Devices found during LE scan should be reported to userspace through
mgmt_device_found events.

Signed-off-by: Andre Guedes <[email protected]>
Acked-by: Marcel Holtmann <[email protected]>
---
net/bluetooth/hci_event.c | 5 +++++
1 files changed, 5 insertions(+), 0 deletions(-)

diff --git a/net/bluetooth/hci_event.c b/net/bluetooth/hci_event.c
index 5e40d4e..c2fe964 100644
--- a/net/bluetooth/hci_event.c
+++ b/net/bluetooth/hci_event.c
@@ -3208,6 +3208,7 @@ static inline void hci_le_adv_report_evt(struct hci_dev *hdev,
{
u8 num_reports = skb->data[0];
void *ptr = &skb->data[1];
+ s8 rssi;

hci_dev_lock(hdev);

@@ -3216,6 +3217,10 @@ static inline void hci_le_adv_report_evt(struct hci_dev *hdev,

hci_add_adv_entry(hdev, ev);

+ rssi = ev->data[ev->length];
+ mgmt_device_found(hdev, &ev->bdaddr, LE_LINK, ev->bdaddr_type,
+ NULL, rssi, 0, ev->data, ev->length);
+
ptr += sizeof(*ev) + ev->length + 1;
}

--
1.7.8.1


2012-01-10 21:20:49

by Andre Guedes

[permalink] [raw]
Subject: [PATCH v2 1/7] Bluetooth: Add 'eir_len' param to mgmt_device_found()

This patch adds a new parameter to mgmt_device_found() to inform
the length of 'eir' pointer.

EIR data from LE advertising report event doesn't have a fixed length
as EIR data from extended inquiry result event does. We needed to
change mgmt_device_found() so it copies 'eir_len' bytes instead of
HCI_MAX_EIR_LENGTH.

Signed-off-by: Andre Guedes <[email protected]>
Acked-by: Marcel Holtmann <[email protected]>
---
include/net/bluetooth/hci_core.h | 2 +-
net/bluetooth/hci_event.c | 10 ++++++----
net/bluetooth/mgmt.c | 7 +++++--
3 files changed, 12 insertions(+), 7 deletions(-)

diff --git a/include/net/bluetooth/hci_core.h b/include/net/bluetooth/hci_core.h
index 59e3541..393acd0 100644
--- a/include/net/bluetooth/hci_core.h
+++ b/include/net/bluetooth/hci_core.h
@@ -925,7 +925,7 @@ int mgmt_read_local_oob_data_reply_complete(struct hci_dev *hdev, u8 *hash,
u8 *randomizer, u8 status);
int mgmt_device_found(struct hci_dev *hdev, bdaddr_t *bdaddr, u8 link_type,
u8 addr_type, u8 *dev_class, s8 rssi,
- u8 cfm_name, u8 *eir);
+ u8 cfm_name, u8 *eir, u8 eir_len);
int mgmt_remote_name(struct hci_dev *hdev, bdaddr_t *bdaddr, u8 *name);
int mgmt_start_discovery_failed(struct hci_dev *hdev, u8 status);
int mgmt_stop_discovery_failed(struct hci_dev *hdev, u8 status);
diff --git a/net/bluetooth/hci_event.c b/net/bluetooth/hci_event.c
index 94a9ca2..5e40d4e 100644
--- a/net/bluetooth/hci_event.c
+++ b/net/bluetooth/hci_event.c
@@ -1608,7 +1608,8 @@ static inline void hci_inquiry_result_evt(struct hci_dev *hdev, struct sk_buff *

name_known = hci_inquiry_cache_update(hdev, &data, false);
mgmt_device_found(hdev, &info->bdaddr, ACL_LINK, 0x00,
- info->dev_class, 0, !name_known, NULL);
+ info->dev_class, 0, !name_known,
+ NULL, 0);
}

hci_dev_unlock(hdev);
@@ -2705,7 +2706,7 @@ static inline void hci_inquiry_result_with_rssi_evt(struct hci_dev *hdev, struct
false);
mgmt_device_found(hdev, &info->bdaddr, ACL_LINK, 0x00,
info->dev_class, info->rssi,
- !name_known, NULL);
+ !name_known, NULL, 0);
}
} else {
struct inquiry_info_with_rssi *info = (void *) (skb->data + 1);
@@ -2723,7 +2724,7 @@ static inline void hci_inquiry_result_with_rssi_evt(struct hci_dev *hdev, struct
false);
mgmt_device_found(hdev, &info->bdaddr, ACL_LINK, 0x00,
info->dev_class, info->rssi,
- !name_known, NULL);
+ !name_known, NULL, 0);
}
}

@@ -2900,7 +2901,8 @@ static inline void hci_extended_inquiry_result_evt(struct hci_dev *hdev, struct
name_known = hci_inquiry_cache_update(hdev, &data, name_known);
mgmt_device_found(hdev, &info->bdaddr, ACL_LINK, 0x00,
info->dev_class, info->rssi,
- !name_known, info->data);
+ !name_known, info->data,
+ sizeof(info->data));
}

hci_dev_unlock(hdev);
diff --git a/net/bluetooth/mgmt.c b/net/bluetooth/mgmt.c
index 2dae2e8..e7bbad8 100644
--- a/net/bluetooth/mgmt.c
+++ b/net/bluetooth/mgmt.c
@@ -2780,10 +2780,13 @@ int mgmt_read_local_oob_data_reply_complete(struct hci_dev *hdev, u8 *hash,

int mgmt_device_found(struct hci_dev *hdev, bdaddr_t *bdaddr, u8 link_type,
u8 addr_type, u8 *dev_class, s8 rssi,
- u8 cfm_name, u8 *eir)
+ u8 cfm_name, u8 *eir, u8 eir_len)
{
struct mgmt_ev_device_found ev;

+ if (eir_len > sizeof(ev.eir))
+ return -EINVAL;
+
memset(&ev, 0, sizeof(ev));

bacpy(&ev.addr.bdaddr, bdaddr);
@@ -2792,7 +2795,7 @@ int mgmt_device_found(struct hci_dev *hdev, bdaddr_t *bdaddr, u8 link_type,
ev.confirm_name = cfm_name;

if (eir)
- memcpy(ev.eir, eir, sizeof(ev.eir));
+ memcpy(ev.eir, eir, eir_len);

if (dev_class)
memcpy(ev.dev_class, dev_class, sizeof(ev.dev_class));
--
1.7.8.1