Skip to content

Commit

Permalink
Bluetooth: Use intervals and tx power from mgmt cmds
Browse files Browse the repository at this point in the history
This patch takes the min/max intervals and tx power optionally provided
in mgmt interface, stores them in the advertisement struct, and uses
them when configuring the hci requests. While tx power is not used if
extended advertising is unavailable, software rotation will use the min
and max advertising intervals specified by the client.

This change is validated manually by ensuring the min/max intervals are
propagated to the controller on both hatch (extended advertising) and
kukui (no extended advertising) chromebooks, and that tx power is
propagated correctly on hatch. These tests are performed with multiple
advertisements simultaneously.

Reviewed-by: Sonny Sasaka <sonnysasaka@chromium.org>
Signed-off-by: Daniel Winkler <danielwinkler@google.com>
Signed-off-by: Marcel Holtmann <marcel@holtmann.org>
Signed-off-by: Johan Hedberg <johan.hedberg@intel.com>
  • Loading branch information
Daniel Winkler authored and Johan Hedberg committed Dec 7, 2020
1 parent 1241057 commit 9bf9f4b
Show file tree
Hide file tree
Showing 4 changed files with 34 additions and 16 deletions.
5 changes: 4 additions & 1 deletion include/net/bluetooth/hci_core.h
Original file line number Diff line number Diff line change
Expand Up @@ -230,6 +230,8 @@ struct adv_info {
__u16 scan_rsp_len;
__u8 scan_rsp_data[HCI_MAX_AD_LENGTH];
__s8 tx_power;
__u32 min_interval;
__u32 max_interval;
bdaddr_t random_addr;
bool rpa_expired;
struct delayed_work rpa_expired_cb;
Expand Down Expand Up @@ -1303,7 +1305,8 @@ struct adv_info *hci_get_next_instance(struct hci_dev *hdev, u8 instance);
int hci_add_adv_instance(struct hci_dev *hdev, u8 instance, u32 flags,
u16 adv_data_len, u8 *adv_data,
u16 scan_rsp_len, u8 *scan_rsp_data,
u16 timeout, u16 duration);
u16 timeout, u16 duration, s8 tx_power,
u32 min_interval, u32 max_interval);
int hci_set_adv_instance_data(struct hci_dev *hdev, u8 instance,
u16 adv_data_len, u8 *adv_data,
u16 scan_rsp_len, u8 *scan_rsp_data);
Expand Down
8 changes: 5 additions & 3 deletions net/bluetooth/hci_core.c
Original file line number Diff line number Diff line change
Expand Up @@ -2951,7 +2951,8 @@ static void adv_instance_rpa_expired(struct work_struct *work)
int hci_add_adv_instance(struct hci_dev *hdev, u8 instance, u32 flags,
u16 adv_data_len, u8 *adv_data,
u16 scan_rsp_len, u8 *scan_rsp_data,
u16 timeout, u16 duration)
u16 timeout, u16 duration, s8 tx_power,
u32 min_interval, u32 max_interval)
{
struct adv_info *adv_instance;

Expand Down Expand Up @@ -2979,6 +2980,9 @@ int hci_add_adv_instance(struct hci_dev *hdev, u8 instance, u32 flags,
adv_instance->flags = flags;
adv_instance->adv_data_len = adv_data_len;
adv_instance->scan_rsp_len = scan_rsp_len;
adv_instance->min_interval = min_interval;
adv_instance->max_interval = max_interval;
adv_instance->tx_power = tx_power;

if (adv_data_len)
memcpy(adv_instance->adv_data, adv_data, adv_data_len);
Expand All @@ -2995,8 +2999,6 @@ int hci_add_adv_instance(struct hci_dev *hdev, u8 instance, u32 flags,
else
adv_instance->duration = duration;

adv_instance->tx_power = HCI_TX_POWER_INVALID;

INIT_DELAYED_WORK(&adv_instance->rpa_expired_cb,
adv_instance_rpa_expired);

Expand Down
29 changes: 19 additions & 10 deletions net/bluetooth/hci_request.c
Original file line number Diff line number Diff line change
Expand Up @@ -1488,13 +1488,15 @@ static bool is_advertising_allowed(struct hci_dev *hdev, bool connectable)
void __hci_req_enable_advertising(struct hci_request *req)
{
struct hci_dev *hdev = req->hdev;
struct adv_info *adv_instance;
struct hci_cp_le_set_adv_param cp;
u8 own_addr_type, enable = 0x01;
bool connectable;
u16 adv_min_interval, adv_max_interval;
u32 flags;

flags = get_adv_instance_flags(hdev, hdev->cur_adv_instance);
adv_instance = hci_find_adv_instance(hdev, hdev->cur_adv_instance);

/* If the "connectable" instance flag was not set, then choose between
* ADV_IND and ADV_NONCONN_IND based on the global connectable setting.
Expand Down Expand Up @@ -1526,11 +1528,16 @@ void __hci_req_enable_advertising(struct hci_request *req)

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

if (connectable) {
cp.type = LE_ADV_IND;

if (adv_instance) {
adv_min_interval = adv_instance->min_interval;
adv_max_interval = adv_instance->max_interval;
} else {
adv_min_interval = hdev->le_adv_min_interval;
adv_max_interval = hdev->le_adv_max_interval;
}

if (connectable) {
cp.type = LE_ADV_IND;
} else {
if (adv_cur_instance_is_scannable(hdev))
cp.type = LE_ADV_SCAN_IND;
Expand All @@ -1541,9 +1548,6 @@ void __hci_req_enable_advertising(struct hci_request *req)
hci_dev_test_flag(hdev, HCI_LIMITED_DISCOVERABLE)) {
adv_min_interval = DISCOV_LE_FAST_ADV_INT_MIN;
adv_max_interval = DISCOV_LE_FAST_ADV_INT_MAX;
} else {
adv_min_interval = hdev->le_adv_min_interval;
adv_max_interval = hdev->le_adv_max_interval;
}
}

Expand Down Expand Up @@ -2119,9 +2123,15 @@ int __hci_req_setup_ext_adv_instance(struct hci_request *req, u8 instance)

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

/* In ext adv set param interval is 3 octets */
hci_cpu_to_le24(hdev->le_adv_min_interval, cp.min_interval);
hci_cpu_to_le24(hdev->le_adv_max_interval, cp.max_interval);
if (adv_instance) {
hci_cpu_to_le24(adv_instance->min_interval, cp.min_interval);
hci_cpu_to_le24(adv_instance->max_interval, cp.max_interval);
cp.tx_power = adv_instance->tx_power;
} else {
hci_cpu_to_le24(hdev->le_adv_min_interval, cp.min_interval);
hci_cpu_to_le24(hdev->le_adv_max_interval, cp.max_interval);
cp.tx_power = HCI_ADV_TX_POWER_NO_PREFERENCE;
}

secondary_adv = (flags & MGMT_ADV_FLAG_SEC_MASK);

Expand All @@ -2144,7 +2154,6 @@ int __hci_req_setup_ext_adv_instance(struct hci_request *req, u8 instance)

cp.own_addr_type = own_addr_type;
cp.channel_map = hdev->le_adv_channel_map;
cp.tx_power = 127;
cp.handle = instance;

if (flags & MGMT_ADV_FLAG_SEC_2M) {
Expand Down
8 changes: 6 additions & 2 deletions net/bluetooth/mgmt.c
Original file line number Diff line number Diff line change
Expand Up @@ -7533,7 +7533,10 @@ static int add_advertising(struct sock *sk, struct hci_dev *hdev,
cp->adv_data_len, cp->data,
cp->scan_rsp_len,
cp->data + cp->adv_data_len,
timeout, duration);
timeout, duration,
HCI_ADV_TX_POWER_NO_PREFERENCE,
hdev->le_adv_min_interval,
hdev->le_adv_max_interval);
if (err < 0) {
err = mgmt_cmd_status(sk, hdev->id, MGMT_OP_ADD_ADVERTISING,
MGMT_STATUS_FAILED);
Expand Down Expand Up @@ -7741,7 +7744,8 @@ static int add_ext_adv_params(struct sock *sk, struct hci_dev *hdev,

/* Create advertising instance with no advertising or response data */
err = hci_add_adv_instance(hdev, cp->instance, flags,
0, NULL, 0, NULL, timeout, duration);
0, NULL, 0, NULL, timeout, duration,
tx_power, min_interval, max_interval);

if (err < 0) {
err = mgmt_cmd_status(sk, hdev->id, MGMT_OP_ADD_EXT_ADV_PARAMS,
Expand Down

0 comments on commit 9bf9f4b

Please sign in to comment.