summaryrefslogtreecommitdiffstats
path: root/net/bluetooth/hci_sync.c
diff options
context:
space:
mode:
authorIulia Tanasescu <iulia.tanasescu@nxp.com>2023-06-19 16:53:16 +0200
committerLuiz Augusto von Dentz <luiz.von.dentz@intel.com>2023-08-11 20:38:12 +0200
commit6a42e9bfd17f7135d59701f93942a3392da482f4 (patch)
treebfa40ccd849f89d955d0e4ba4b1e527016a7564d /net/bluetooth/hci_sync.c
parentBluetooth: hci_sock: Forward credentials to monitor (diff)
downloadlinux-6a42e9bfd17f7135d59701f93942a3392da482f4.tar.xz
linux-6a42e9bfd17f7135d59701f93942a3392da482f4.zip
Bluetooth: ISO: Support multiple BIGs
This adds support for creating multiple BIGs. According to spec, each BIG shall have an unique handle, and each BIG should be associated with a different advertising handle. Otherwise, the LE Create BIG command will fail, with error code Command Disallowed (for reusing a BIG handle), or Unknown Advertising Identifier (for reusing an advertising handle). The btmon snippet below shows an exercise for creating two BIGs for the same controller, by opening two isotest instances with the following command: tools/isotest -i hci0 -s 00:00:00:00:00:00 < HCI Command: LE Create Broadcast Isochronous Group (0x08|0x0068) plen 31 Handle: 0x00 Advertising Handle: 0x01 Number of BIS: 1 SDU Interval: 10000 us (0x002710) Maximum SDU size: 40 Maximum Latency: 10 ms (0x000a) RTN: 0x02 PHY: LE 2M (0x02) Packing: Sequential (0x00) Framing: Unframed (0x00) Encryption: 0x00 Broadcast Code: 00000000000000000000000000000000 > HCI Event: Command Status (0x0f) plen 4 LE Create Broadcast Isochronous Group (0x08|0x0068) ncmd 1 Status: Success (0x00) > HCI Event: LE Meta Event (0x3e) plen 21 LE Broadcast Isochronous Group Complete (0x1b) Status: Success (0x00) Handle: 0x00 BIG Synchronization Delay: 912 us (0x000390) Transport Latency: 912 us (0x000390) PHY: LE 2M (0x02) NSE: 3 BN: 1 PTO: 1 IRC: 3 Maximum PDU: 40 ISO Interval: 10.00 msec (0x0008) Connection Handle #0: 10 < HCI Command: LE Create Broadcast Isochronous Group (0x08|0x0068) Handle: 0x01 Advertising Handle: 0x02 Number of BIS: 1 SDU Interval: 10000 us (0x002710) Maximum SDU size: 40 Maximum Latency: 10 ms (0x000a) RTN: 0x02 PHY: LE 2M (0x02) Packing: Sequential (0x00) Framing: Unframed (0x00) Encryption: 0x00 Broadcast Code: 00000000000000000000000000000000 > HCI Event: Command Status (0x0f) plen 4 LE Create Broadcast Isochronous Group (0x08|0x0068) ncmd 1 Status: Success (0x00) Signed-off-by: Iulia Tanasescu <iulia.tanasescu@nxp.com> Signed-off-by: Luiz Augusto von Dentz <luiz.von.dentz@intel.com>
Diffstat (limited to 'net/bluetooth/hci_sync.c')
-rw-r--r--net/bluetooth/hci_sync.c28
1 files changed, 15 insertions, 13 deletions
diff --git a/net/bluetooth/hci_sync.c b/net/bluetooth/hci_sync.c
index b617d1dd247a..afb8e970e62c 100644
--- a/net/bluetooth/hci_sync.c
+++ b/net/bluetooth/hci_sync.c
@@ -3,6 +3,7 @@
* BlueZ - Bluetooth protocol stack for Linux
*
* Copyright (C) 2021 Intel Corporation
+ * Copyright 2023 NXP
*/
#include <linux/property.h>
@@ -1319,9 +1320,11 @@ int hci_start_ext_adv_sync(struct hci_dev *hdev, u8 instance)
static int hci_disable_per_advertising_sync(struct hci_dev *hdev, u8 instance)
{
struct hci_cp_le_set_per_adv_enable cp;
+ struct adv_info *adv = NULL;
/* If periodic advertising already disabled there is nothing to do. */
- if (!hci_dev_test_flag(hdev, HCI_LE_PER_ADV))
+ adv = hci_find_adv_instance(hdev, instance);
+ if (!adv || !adv->periodic || !adv->enabled)
return 0;
memset(&cp, 0, sizeof(cp));
@@ -1386,9 +1389,11 @@ static int hci_set_per_adv_data_sync(struct hci_dev *hdev, u8 instance)
static int hci_enable_per_advertising_sync(struct hci_dev *hdev, u8 instance)
{
struct hci_cp_le_set_per_adv_enable cp;
+ struct adv_info *adv = NULL;
/* If periodic advertising already enabled there is nothing to do. */
- if (hci_dev_test_flag(hdev, HCI_LE_PER_ADV))
+ adv = hci_find_adv_instance(hdev, instance);
+ if (adv && adv->periodic && adv->enabled)
return 0;
memset(&cp, 0, sizeof(cp));
@@ -1458,22 +1463,19 @@ int hci_start_per_adv_sync(struct hci_dev *hdev, u8 instance, u8 data_len,
sync_interval);
if (IS_ERR(adv))
return PTR_ERR(adv);
+ adv->pending = false;
added = true;
}
}
- /* Only start advertising if instance 0 or if a dedicated instance has
- * been added.
- */
- if (!adv || added) {
- err = hci_start_ext_adv_sync(hdev, instance);
- if (err < 0)
- goto fail;
+ /* Start advertising */
+ err = hci_start_ext_adv_sync(hdev, instance);
+ if (err < 0)
+ goto fail;
- err = hci_adv_bcast_annoucement(hdev, adv);
- if (err < 0)
- goto fail;
- }
+ err = hci_adv_bcast_annoucement(hdev, adv);
+ if (err < 0)
+ goto fail;
err = hci_set_per_adv_params_sync(hdev, instance, min_interval,
max_interval);