Skip to content

Commit 5725bc6

Browse files
committed
Bluetooth: hci_sync: Fix broadcast/PA when using an existing instance
When using and existing adv_info instance for broadcast source it needs to be updated to periodic first before it can be reused, also in case the existing instance already have data hci_set_adv_instance_data cannot be used directly since it would overwrite the existing data so this reappend the original data after the Broadcast ID, if one was generated. Example: bluetoothctl># Add PBP to EA so it can be later referenced as the BIS ID bluetoothctl> advertise.service 0x1856 0x00 0x00 bluetoothctl> advertise on ... < HCI Command: LE Set Extended Advertising Data (0x08|0x0037) plen 13 Handle: 0x01 Operation: Complete extended advertising data (0x03) Fragment preference: Minimize fragmentation (0x01) Data length: 0x09 Service Data: Public Broadcast Announcement (0x1856) Data[2]: 0000 Flags: 0x06 LE General Discoverable Mode BR/EDR Not Supported ... bluetoothctl># Attempt to acquire Broadcast Source transport bluetoothctl>transport.acquire /org/bluez/hci0/pac_bcast0/fd0 ... < HCI Command: LE Set Extended Advertising Data (0x08|0x0037) plen 255 Handle: 0x01 Operation: Complete extended advertising data (0x03) Fragment preference: Minimize fragmentation (0x01) Data length: 0x0e Service Data: Broadcast Audio Announcement (0x1852) Broadcast ID: 11371620 (0xad8464) Service Data: Public Broadcast Announcement (0x1856) Data[2]: 0000 Flags: 0x06 LE General Discoverable Mode BR/EDR Not Supported Link: bluez/bluez#1117 Fixes: eca0ae4 ("Bluetooth: Add initial implementation of BIS connections") Signed-off-by: Luiz Augusto von Dentz <[email protected]>
1 parent 20a2aa0 commit 5725bc6

File tree

1 file changed

+15
-5
lines changed

1 file changed

+15
-5
lines changed

net/bluetooth/hci_sync.c

Lines changed: 15 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1559,7 +1559,8 @@ static int hci_enable_per_advertising_sync(struct hci_dev *hdev, u8 instance)
15591559
static int hci_adv_bcast_annoucement(struct hci_dev *hdev, struct adv_info *adv)
15601560
{
15611561
u8 bid[3];
1562-
u8 ad[4 + 3];
1562+
u8 ad[HCI_MAX_EXT_AD_LENGTH];
1563+
u8 len;
15631564

15641565
/* Skip if NULL adv as instance 0x00 is used for general purpose
15651566
* advertising so it cannot used for the likes of Broadcast Announcement
@@ -1585,8 +1586,10 @@ static int hci_adv_bcast_annoucement(struct hci_dev *hdev, struct adv_info *adv)
15851586

15861587
/* Generate Broadcast ID */
15871588
get_random_bytes(bid, sizeof(bid));
1588-
eir_append_service_data(ad, 0, 0x1852, bid, sizeof(bid));
1589-
hci_set_adv_instance_data(hdev, adv->instance, sizeof(ad), ad, 0, NULL);
1589+
len = eir_append_service_data(ad, 0, 0x1852, bid, sizeof(bid));
1590+
memcpy(ad + len, adv->adv_data, adv->adv_data_len);
1591+
hci_set_adv_instance_data(hdev, adv->instance, len + adv->adv_data_len,
1592+
ad, 0, NULL);
15901593

15911594
return hci_update_adv_data_sync(hdev, adv->instance);
15921595
}
@@ -1603,8 +1606,15 @@ int hci_start_per_adv_sync(struct hci_dev *hdev, u8 instance, u8 data_len,
16031606

16041607
if (instance) {
16051608
adv = hci_find_adv_instance(hdev, instance);
1606-
/* Create an instance if that could not be found */
1607-
if (!adv) {
1609+
if (adv) {
1610+
/* Turn it into periodic advertising */
1611+
adv->periodic = true;
1612+
adv->per_adv_data_len = data_len;
1613+
if (data)
1614+
memcpy(adv->per_adv_data, data, data_len);
1615+
adv->flags = flags;
1616+
} else if (!adv) {
1617+
/* Create an instance if that could not be found */
16081618
adv = hci_add_per_instance(hdev, instance, flags,
16091619
data_len, data,
16101620
sync_interval,

0 commit comments

Comments
 (0)