Skip to content

Commit

Permalink
Bluetooth: Fix tracking of advertising state
Browse files Browse the repository at this point in the history
This fix not being able to stop advertising while connected due to
invalid use of BT_DEV_ADVERTISING flag.

Change-Id: If5578fa2c69dd18d6623d05ae44d4710cce9a9e5
Signed-off-by: Szymon Janc <ext.szymon.janc@tieto.com>
  • Loading branch information
Szymon Janc authored and Gerrit Code Review committed Feb 17, 2016
1 parent 086dfc2 commit b7b0a16
Show file tree
Hide file tree
Showing 2 changed files with 70 additions and 27 deletions.
96 changes: 69 additions & 27 deletions net/bluetooth/hci_core.c
Original file line number Diff line number Diff line change
Expand Up @@ -324,6 +324,54 @@ static const bt_addr_le_t *find_id_addr(const bt_addr_le_t *addr)
return addr;
}

static int set_advertise_enable(void)
{
struct net_buf *buf;
int err;

if (atomic_test_bit(bt_dev.flags, BT_DEV_ADVERTISING)) {
return 0;
}

buf = bt_hci_cmd_create(BT_HCI_OP_LE_SET_ADV_ENABLE, 1);
if (!buf) {
return -ENOBUFS;
}

net_buf_add_u8(buf, BT_HCI_LE_ADV_ENABLE);
err = bt_hci_cmd_send_sync(BT_HCI_OP_LE_SET_ADV_ENABLE, buf, NULL);
if (err) {
return err;
}

atomic_set_bit(bt_dev.flags, BT_DEV_ADVERTISING);
return 0;
}

static int set_advertise_disable(void)
{
struct net_buf *buf;
int err;

if (!atomic_test_bit(bt_dev.flags, BT_DEV_ADVERTISING)) {
return 0;
}

buf = bt_hci_cmd_create(BT_HCI_OP_LE_SET_ADV_ENABLE, 1);
if (!buf) {
return -ENOBUFS;
}

net_buf_add_u8(buf, BT_HCI_LE_ADV_DISABLE);
err = bt_hci_cmd_send_sync(BT_HCI_OP_LE_SET_ADV_ENABLE, buf, NULL);
if (err) {
return err;
}

atomic_clear_bit(bt_dev.flags, BT_DEV_ADVERTISING);
return 0;
}

#if defined(CONFIG_BLUETOOTH_CONN)
static void hci_acl(struct net_buf *buf)
{
Expand Down Expand Up @@ -468,14 +516,8 @@ static void hci_disconn_complete(struct net_buf *buf)

bt_conn_unref(conn);

if (atomic_test_bit(bt_dev.flags, BT_DEV_ADVERTISING)) {
struct net_buf *buf;

buf = bt_hci_cmd_create(BT_HCI_OP_LE_SET_ADV_ENABLE, 1);
if (buf) {
net_buf_add_u8(buf, BT_HCI_LE_ADV_ENABLE);
bt_hci_cmd_send(BT_HCI_OP_LE_SET_ADV_ENABLE, buf);
}
if (atomic_test_bit(bt_dev.flags, BT_DEV_KEEP_ADVERTISING)) {
set_advertise_enable();
}
}

Expand Down Expand Up @@ -545,6 +587,14 @@ static void le_conn_complete(struct net_buf *buf)
return;
}

/*
* clear advertising even if we are not able to add connection object
* to keep host in sync with controller state
*/
if (evt->role == BT_CONN_ROLE_SLAVE) {
atomic_clear_bit(bt_dev.flags, BT_DEV_ADVERTISING);
}

if (!conn) {
conn = bt_conn_add_le(id_addr);
}
Expand Down Expand Up @@ -2473,10 +2523,15 @@ int bt_le_adv_start(const struct bt_le_adv_param *param,
return -EINVAL;
}

if (atomic_test_bit(bt_dev.flags, BT_DEV_ADVERTISING)) {
if (atomic_test_bit(bt_dev.flags, BT_DEV_KEEP_ADVERTISING)) {
return -EALREADY;
}

err = set_advertise_disable();
if (err) {
return err;
}

err = set_ad(BT_HCI_OP_LE_SET_ADV_DATA, ad, ad_len);
if (err) {
return err;
Expand Down Expand Up @@ -2521,43 +2576,30 @@ int bt_le_adv_start(const struct bt_le_adv_param *param,

bt_hci_cmd_send(BT_HCI_OP_LE_SET_ADV_PARAMETERS, buf);

buf = bt_hci_cmd_create(BT_HCI_OP_LE_SET_ADV_ENABLE, 1);
if (!buf) {
return -ENOBUFS;
}

net_buf_add_u8(buf, BT_HCI_LE_ADV_ENABLE);
err = bt_hci_cmd_send_sync(BT_HCI_OP_LE_SET_ADV_ENABLE, buf, NULL);
err = set_advertise_enable();
if (err) {
return err;
}

atomic_set_bit(bt_dev.flags, BT_DEV_ADVERTISING);
atomic_set_bit(bt_dev.flags, BT_DEV_KEEP_ADVERTISING);

return 0;
}

int bt_le_adv_stop(void)
{
struct net_buf *buf;
int err;

if (!atomic_test_bit(bt_dev.flags, BT_DEV_ADVERTISING)) {
if (!atomic_test_bit(bt_dev.flags, BT_DEV_KEEP_ADVERTISING)) {
return -EALREADY;
}

buf = bt_hci_cmd_create(BT_HCI_OP_LE_SET_ADV_ENABLE, 1);
if (!buf) {
return -ENOBUFS;
}

net_buf_add_u8(buf, BT_HCI_LE_ADV_DISABLE);
err = bt_hci_cmd_send_sync(BT_HCI_OP_LE_SET_ADV_ENABLE, buf, NULL);
err = set_advertise_disable();
if (err) {
return err;
}

atomic_clear_bit(bt_dev.flags, BT_DEV_ADVERTISING);
atomic_clear_bit(bt_dev.flags, BT_DEV_KEEP_ADVERTISING);

return 0;
}
Expand Down
1 change: 1 addition & 0 deletions net/bluetooth/hci_core.h
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@ enum {
BT_DEV_READY,

BT_DEV_ADVERTISING,
BT_DEV_KEEP_ADVERTISING,
BT_DEV_SCANNING,
BT_DEV_EXPLICIT_SCAN,

Expand Down

0 comments on commit b7b0a16

Please sign in to comment.