Skip to content

Commit

Permalink
---
Browse files Browse the repository at this point in the history
yaml
---
r: 290929
b: refs/heads/master
c: 7ba8b4b
h: refs/heads/master
i:
  290927: d72cf2a
v: v3
  • Loading branch information
Andre Guedes authored and Johan Hedberg committed Feb 13, 2012
1 parent ee776e8 commit f22d61a
Show file tree
Hide file tree
Showing 4 changed files with 93 additions and 4 deletions.
2 changes: 1 addition & 1 deletion [refs]
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
---
refs/heads/master: 6fbe195dc41c4fae1fa7aca1a38c888de1d24e2d
refs/heads/master: 7ba8b4be38e7c83b2b13333a82a0ecde921a7390
8 changes: 8 additions & 0 deletions trunk/include/net/bluetooth/hci_core.h
Original file line number Diff line number Diff line change
Expand Up @@ -122,6 +122,12 @@ struct adv_entry {
u8 bdaddr_type;
};

struct le_scan_params {
u8 type;
u16 interval;
u16 window;
};

#define NUM_REASSEMBLY 4
struct hci_dev {
struct list_head list;
Expand Down Expand Up @@ -261,6 +267,8 @@ struct hci_dev {

unsigned long dev_flags;

struct delayed_work le_scan_disable;

int (*open)(struct hci_dev *hdev);
int (*close)(struct hci_dev *hdev);
int (*flush)(struct hci_dev *hdev);
Expand Down
74 changes: 74 additions & 0 deletions trunk/net/bluetooth/hci_core.c
Original file line number Diff line number Diff line change
Expand Up @@ -759,6 +759,8 @@ 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_delayed_work_sync(&hdev->le_scan_disable);

hci_dev_lock(hdev);
inquiry_cache_flush(hdev);
hci_conn_hash_flush(hdev);
Expand Down Expand Up @@ -1596,6 +1598,76 @@ int hci_add_adv_entry(struct hci_dev *hdev,
return 0;
}

static void le_scan_param_req(struct hci_dev *hdev, unsigned long opt)
{
struct le_scan_params *param = (struct le_scan_params *) opt;
struct hci_cp_le_set_scan_param cp;

memset(&cp, 0, sizeof(cp));
cp.type = param->type;
cp.interval = cpu_to_le16(param->interval);
cp.window = cpu_to_le16(param->window);

hci_send_cmd(hdev, HCI_OP_LE_SET_SCAN_PARAM, sizeof(cp), &cp);
}

static void le_scan_enable_req(struct hci_dev *hdev, unsigned long opt)
{
struct hci_cp_le_set_scan_enable cp;

memset(&cp, 0, sizeof(cp));
cp.enable = 1;

hci_send_cmd(hdev, HCI_OP_LE_SET_SCAN_ENABLE, sizeof(cp), &cp);
}

static int hci_do_le_scan(struct hci_dev *hdev, u8 type, u16 interval,
u16 window, int timeout)
{
long timeo = msecs_to_jiffies(3000);
struct le_scan_params param;
int err;

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

if (test_bit(HCI_LE_SCAN, &hdev->dev_flags))
return -EINPROGRESS;

param.type = type;
param.interval = interval;
param.window = window;

hci_req_lock(hdev);

err = __hci_request(hdev, le_scan_param_req, (unsigned long) &param,
timeo);
if (!err)
err = __hci_request(hdev, le_scan_enable_req, 0, timeo);

hci_req_unlock(hdev);

if (err < 0)
return err;

schedule_delayed_work(&hdev->le_scan_disable,
msecs_to_jiffies(timeout));

return 0;
}

static void le_scan_disable_work(struct work_struct *work)
{
struct hci_dev *hdev = container_of(work, struct hci_dev,
le_scan_disable.work);
struct hci_cp_le_set_scan_enable cp;

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

memset(&cp, 0, sizeof(cp));

hci_send_cmd(hdev, HCI_OP_LE_SET_SCAN_ENABLE, sizeof(cp), &cp);
}

/* Register HCI device */
int hci_register_dev(struct hci_dev *hdev)
{
Expand Down Expand Up @@ -1682,6 +1754,8 @@ int hci_register_dev(struct hci_dev *hdev)

atomic_set(&hdev->promisc, 0);

INIT_DELAYED_WORK(&hdev->le_scan_disable, le_scan_disable_work);

write_unlock(&hci_dev_list_lock);

hdev->workqueue = alloc_workqueue(hdev->name, WQ_HIGHPRI | WQ_UNBOUND |
Expand Down
13 changes: 10 additions & 3 deletions trunk/net/bluetooth/hci_event.c
Original file line number Diff line number Diff line change
Expand Up @@ -1031,6 +1031,8 @@ 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);

hci_req_complete(hdev, HCI_OP_LE_SET_SCAN_PARAM, status);
}

static void hci_cc_le_set_scan_enable(struct hci_dev *hdev,
Expand All @@ -1041,15 +1043,17 @@ 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:
hci_req_complete(hdev, HCI_OP_LE_SET_SCAN_ENABLE, status);

if (status)
return;

set_bit(HCI_LE_SCAN, &hdev->dev_flags);

cancel_delayed_work_sync(&hdev->adv_work);
Expand All @@ -1061,6 +1065,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);
Expand Down

0 comments on commit f22d61a

Please sign in to comment.