Skip to content

Commit e77f43d

Browse files
committed
Bluetooth: hci_core: Fix not handling hdev->le_num_of_adv_sets=1
If hdev->le_num_of_adv_sets is set to 1 it means that only handle 0x00 can be used, but since the MGMT interface instances start from 1 (instance 0 means all instances in case of MGMT_OP_REMOVE_ADVERTISING) the code needs to map the instance to handle otherwise users will not be able to advertise as instance 1 would attempt to use handle 0x01. Fixes: 1d0fac2 ("Bluetooth: Use controller sets when available") Signed-off-by: Luiz Augusto von Dentz <[email protected]>
1 parent 36b1c9c commit e77f43d

File tree

3 files changed

+18
-9
lines changed

3 files changed

+18
-9
lines changed

include/net/bluetooth/hci_core.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -246,6 +246,7 @@ struct adv_info {
246246
bool periodic;
247247
__u8 mesh;
248248
__u8 instance;
249+
__u8 handle;
249250
__u32 flags;
250251
__u16 timeout;
251252
__u16 remaining_time;

net/bluetooth/hci_core.c

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1765,6 +1765,15 @@ struct adv_info *hci_add_adv_instance(struct hci_dev *hdev, u8 instance,
17651765

17661766
adv->pending = true;
17671767
adv->instance = instance;
1768+
1769+
/* If controller support only one set and the instance is set to
1770+
* 1 then there is no option other than using handle 0x00.
1771+
*/
1772+
if (hdev->le_num_of_adv_sets == 1 && instance == 1)
1773+
adv->handle = 0x00;
1774+
else
1775+
adv->handle = instance;
1776+
17681777
list_add(&adv->list, &hdev->adv_instances);
17691778
hdev->adv_instance_cnt++;
17701779
}

net/bluetooth/hci_sync.c

Lines changed: 8 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1043,11 +1043,10 @@ static int hci_disable_ext_adv_instance_sync(struct hci_dev *hdev, u8 instance)
10431043
struct hci_cp_ext_adv_set *set;
10441044
u8 data[sizeof(*cp) + sizeof(*set) * 1];
10451045
u8 size;
1046+
struct adv_info *adv = NULL;
10461047

10471048
/* If request specifies an instance that doesn't exist, fail */
10481049
if (instance > 0) {
1049-
struct adv_info *adv;
1050-
10511050
adv = hci_find_adv_instance(hdev, instance);
10521051
if (!adv)
10531052
return -EINVAL;
@@ -1066,7 +1065,7 @@ static int hci_disable_ext_adv_instance_sync(struct hci_dev *hdev, u8 instance)
10661065
cp->num_of_sets = !!instance;
10671066
cp->enable = 0x00;
10681067

1069-
set->handle = instance;
1068+
set->handle = adv ? adv->handle : instance;
10701069

10711070
size = sizeof(*cp) + sizeof(*set) * cp->num_of_sets;
10721071

@@ -1249,7 +1248,7 @@ static int hci_set_ext_scan_rsp_data_sync(struct hci_dev *hdev, u8 instance)
12491248

12501249
len = eir_create_scan_rsp(hdev, instance, pdu->data);
12511250

1252-
pdu->handle = instance;
1251+
pdu->handle = adv ? adv->handle : instance;
12531252
pdu->length = len;
12541253
pdu->operation = LE_SET_ADV_DATA_OP_COMPLETE;
12551254
pdu->frag_pref = LE_SET_ADV_DATA_NO_FRAG;
@@ -1331,7 +1330,7 @@ int hci_enable_ext_advertising_sync(struct hci_dev *hdev, u8 instance)
13311330

13321331
memset(set, 0, sizeof(*set));
13331332

1334-
set->handle = instance;
1333+
set->handle = adv ? adv->handle : instance;
13351334

13361335
/* Set duration per instance since controller is responsible for
13371336
* scheduling it.
@@ -1410,18 +1409,18 @@ static int hci_set_per_adv_data_sync(struct hci_dev *hdev, u8 instance)
14101409
DEFINE_FLEX(struct hci_cp_le_set_per_adv_data, pdu, data, length,
14111410
HCI_MAX_PER_AD_LENGTH);
14121411
u8 len;
1412+
struct adv_info *adv = NULL;
14131413

14141414
if (instance) {
1415-
struct adv_info *adv = hci_find_adv_instance(hdev, instance);
1416-
1415+
adv = hci_find_adv_instance(hdev, instance);
14171416
if (!adv || !adv->periodic)
14181417
return 0;
14191418
}
14201419

14211420
len = eir_create_per_adv_data(hdev, instance, pdu->data);
14221421

14231422
pdu->length = len;
1424-
pdu->handle = instance;
1423+
pdu->handle = adv ? adv->handle : instance;
14251424
pdu->operation = LE_SET_ADV_DATA_OP_COMPLETE;
14261425

14271426
return __hci_cmd_sync_status(hdev, HCI_OP_LE_SET_PER_ADV_DATA,
@@ -1734,7 +1733,7 @@ static int hci_set_ext_adv_data_sync(struct hci_dev *hdev, u8 instance)
17341733
len = eir_create_adv_data(hdev, instance, pdu->data);
17351734

17361735
pdu->length = len;
1737-
pdu->handle = instance;
1736+
pdu->handle = adv ? adv->handle : instance;
17381737
pdu->operation = LE_SET_ADV_DATA_OP_COMPLETE;
17391738
pdu->frag_pref = LE_SET_ADV_DATA_NO_FRAG;
17401739

0 commit comments

Comments
 (0)