* [PATCH BlueZ v3 2/6] emulator: Add initial support for PAST
2025-10-14 20:33 [PATCH BlueZ v3 1/6] monitor: Use PAST to refer to Periodic Advertising Sync Transfer Luiz Augusto von Dentz
@ 2025-10-14 20:33 ` Luiz Augusto von Dentz
2025-10-14 20:33 ` [PATCH BlueZ v3 3/6] iso-tester: Add tests for PAST procedures Luiz Augusto von Dentz
` (5 subsequent siblings)
6 siblings, 0 replies; 8+ messages in thread
From: Luiz Augusto von Dentz @ 2025-10-14 20:33 UTC (permalink / raw)
To: linux-bluetooth
From: Luiz Augusto von Dentz <luiz.von.dentz@intel.com>
---
client/scripts/broadcast-sink.bt | 2 +-
emulator/btdev.c | 333 +++++++++++++++++++++++++++++--
emulator/bthost.c | 43 ++++
emulator/bthost.h | 3 +-
4 files changed, 358 insertions(+), 23 deletions(-)
diff --git a/client/scripts/broadcast-sink.bt b/client/scripts/broadcast-sink.bt
index b912231b248f..b26dc44ac237 100644
--- a/client/scripts/broadcast-sink.bt
+++ b/client/scripts/broadcast-sink.bt
@@ -4,4 +4,4 @@ y
a
3
4
-scan on
\ No newline at end of file
+scan on
diff --git a/emulator/btdev.c b/emulator/btdev.c
index 1a0f9ef2de58..8c72a24290c6 100644
--- a/emulator/btdev.c
+++ b/emulator/btdev.c
@@ -52,9 +52,10 @@
#define has_bredr(btdev) (!((btdev)->features[4] & 0x20))
#define has_le(btdev) (!!((btdev)->features[4] & 0x40))
-#define ACL_HANDLE 42
-#define ISO_HANDLE 257
-#define SCO_HANDLE 257
+#define ACL_HANDLE BIT(0)
+#define SCO_HANDLE BIT(8)
+#define CIS_HANDLE SCO_HANDLE
+#define BIS_HANDLE BIT(9)
#define SYNC_HANDLE 1
#define INV_HANDLE 0xffff
@@ -72,8 +73,10 @@ struct hook {
struct btdev_conn {
uint16_t handle;
uint8_t type;
+ uint8_t past_mode;
struct btdev *dev;
struct btdev_conn *link;
+ struct queue *links;
void *data;
};
@@ -386,7 +389,7 @@ static inline struct btdev *find_btdev_by_bdaddr_type(const uint8_t *bdaddr,
if (!dev)
continue;
- if (bdaddr_type == 0x01)
+ if (bdaddr_type == 0x01 || bdaddr_type == 0x03)
cmp = memcmp(dev->random_addr, bdaddr, 6);
else
cmp = memcmp(dev->bdaddr, bdaddr, 6);
@@ -395,7 +398,7 @@ static inline struct btdev *find_btdev_by_bdaddr_type(const uint8_t *bdaddr,
return dev;
/* Check for instance own Random addresses */
- if (bdaddr_type == 0x01) {
+ if (bdaddr_type == 0x01 || bdaddr_type == 0x03) {
adv = queue_find(dev->le_ext_adv, match_adv_addr,
bdaddr);
if (adv)
@@ -566,10 +569,15 @@ static void conn_remove(void *data)
if (conn->link) {
struct btdev_conn *link = conn->link;
- conn_unlink(conn, conn->link);
- conn_remove(link);
+ if (link->link == conn) {
+ conn_unlink(conn, conn->link);
+ conn_remove(link);
+ } else
+ queue_remove(link->links, conn);
}
+ queue_destroy(conn->links, conn_remove);
+
queue_remove(conn->dev->conns, conn);
free(conn->data);
@@ -1225,7 +1233,7 @@ static struct btdev_conn *find_bis_index(const struct btdev *remote,
conn = entry->data;
/* Skip if not a broadcast */
- if (conn->type != HCI_ISODATA_PKT || conn->link)
+ if (conn->type != HCI_ISODATA_PKT && conn->handle < BIS_HANDLE)
continue;
if (!index)
@@ -1247,11 +1255,22 @@ static struct btdev_conn *conn_link_bis(struct btdev *dev, struct btdev *remote,
if (!bis)
return NULL;
- conn = conn_add_bis(dev, ISO_HANDLE, bis->data);
+ conn = conn_add_bis(dev, BIS_HANDLE, bis->data);
if (!conn)
return NULL;
- bis->link = conn;
+ if (!bis->link) {
+ bis->link = conn;
+ } else {
+ if (!bis->links)
+ bis->links = queue_new();
+
+ if (!queue_push_tail(bis->links, conn)) {
+ conn_remove(conn);
+ return NULL;
+ }
+ }
+
conn->link = bis;
util_debug(dev->debug_callback, dev->debug_data,
@@ -5466,6 +5485,9 @@ static void le_pa_sync_estabilished(struct btdev *dev, struct btdev *remote,
struct le_ext_adv *ext_adv;
uint16_t sync_handle = SYNC_HANDLE;
+ if (!remote)
+ return;
+
per_adv = queue_find(dev->le_per_adv, match_dev, remote);
if (!per_adv)
return;
@@ -6025,6 +6047,258 @@ static void set_le_50_commands(struct btdev *btdev)
btdev->cmds = cmd_le_5_0;
}
+static void le_past_received_event(struct btdev_conn *acl,
+ struct bt_hci_evt_le_past_recv *ev,
+ struct le_per_adv *pa)
+{
+ struct btdev *remote;
+
+ le_meta_event(acl->dev, BT_HCI_EVT_LE_PAST_RECEIVED, ev, sizeof(*ev));
+
+ if (ev->status != BT_HCI_ERR_SUCCESS)
+ return;
+
+ remote = find_btdev_by_bdaddr_type(pa->addr, pa->addr_type);
+ if (!remote)
+ return;
+
+ switch (acl->past_mode) {
+ case 0x01:
+ /* HCI_LE_Periodic_Advertising_Report events will be
+ * disabled.
+ */
+ break;
+ case 0x02:
+ /* HCI_LE_Periodic_Advertising_Report events will be enabled
+ * with duplicate filtering disabled.
+ */
+ case 0x03:
+ /* HCI_LE_Periodic_Advertising_Report events will be enabled
+ * with duplicate filtering enabled.
+ */
+ send_pa(acl->dev, remote, 0, pa->sync_handle);
+ break;
+ }
+}
+
+static void le_past_received(struct btdev_conn *acl, struct le_per_adv *pa)
+{
+ struct btdev *dev = acl->dev;
+ struct bt_hci_evt_le_past_recv ev;
+ struct le_per_adv *cp;
+ uint16_t sync_handle = SYNC_HANDLE;
+
+ /* 0x00:
+ * No attempt is made to synchronize to the periodic advertising and no
+ * HCI_LE_Periodic_Advertising_Sync_Transfer_Received event is sent to
+ * the Host.
+ */
+ if (!acl->past_mode)
+ return;
+
+ memset(&ev, 0, sizeof(ev));
+ ev.status = BT_HCI_ERR_SUCCESS;
+
+ /* Create a copy of the PA sync */
+ cp = le_per_adv_new(dev, pa->addr_type, pa->addr, pa->sid);
+ if (!cp) {
+ ev.status = BT_HCI_ERR_MEM_CAPACITY_EXCEEDED;
+ goto done;
+ }
+
+ /* Find the next available sync handle */
+ while (queue_find(dev->le_per_adv, match_sync_handle,
+ UINT_TO_PTR(sync_handle)))
+ sync_handle++;
+
+ cp->sync_handle = sync_handle;
+
+ ev.handle = cpu_to_le16(acl->handle);
+ ev.sync_handle = cpu_to_le16(cp->sync_handle);
+ ev.sid = cpu_to_le16(cp->sid);
+ ev.addr_type = cp->addr_type;
+ memcpy(ev.addr, cp->addr, sizeof(ev.addr));
+ ev.phy = 0x01;
+ ev.interval = acl->dev->le_pa_min_interval;
+ ev.clock_accuracy = 0x07;
+
+done:
+ le_past_received_event(acl, &ev, pa);
+}
+
+static int cmd_past(struct btdev *dev, const void *data, uint8_t len)
+{
+ const struct bt_hci_cmd_le_past *cmd = data;
+ struct bt_hci_rsp_le_past rsp;
+ struct le_per_adv *pa;
+ struct btdev_conn *acl = NULL;
+
+ memset(&rsp, 0, sizeof(rsp));
+
+ rsp.status = BT_HCI_ERR_SUCCESS;
+ rsp.handle = cmd->handle;
+
+ pa = queue_find(dev->le_per_adv, match_sync_handle,
+ UINT_TO_PTR(le16_to_cpu(cmd->sync_handle)));
+ if (!pa) {
+ /* If the periodic advertising train corresponding to the
+ * Sync_Handle parameter does not exist, the Controller shall
+ * return the error code Unknown Advertising Identifier (0x42).
+ */
+ rsp.status = BT_HCI_ERR_UNKNOWN_ADVERTISING_ID;
+ goto done;
+ }
+
+ acl = queue_find(dev->conns, match_handle,
+ UINT_TO_PTR(le16_to_cpu(cmd->handle)));
+ if (!acl) {
+ /* If the Connection_Handle parameter does not identify a
+ * current connection, the Controller shall return the error
+ * code Unknown Connection Identifier (0x02).
+ */
+ rsp.status = BT_HCI_ERR_UNKNOWN_CONN_ID;
+ goto done;
+ }
+
+done:
+ cmd_complete(dev, BT_HCI_CMD_LE_PAST, &rsp, sizeof(rsp));
+
+ if (rsp.status == BT_HCI_ERR_SUCCESS)
+ le_past_received(acl->link, pa);
+
+ return 0;
+}
+
+static void le_past_info_received(struct btdev_conn *acl, struct le_ext_adv *ea)
+{
+ struct btdev *dev = acl->dev;
+ struct bt_hci_evt_le_past_recv ev;
+ struct le_per_adv *pa;
+ uint16_t sync_handle = SYNC_HANDLE;
+
+ /* 0x00:
+ * No attempt is made to synchronize to the periodic advertising and no
+ * HCI_LE_Periodic_Advertising_Sync_Transfer_Received event is sent to
+ * the Host.
+ */
+ if (!acl->past_mode)
+ return;
+
+ memset(&ev, 0, sizeof(ev));
+ ev.status = BT_HCI_ERR_SUCCESS;
+
+ /* Create a copy using EA parameters */
+ pa = le_per_adv_new(dev, ea->own_addr_type,
+ ea->own_addr_type ? ea->random_addr :
+ acl->link->dev->bdaddr, ea->sid);
+ if (!pa) {
+ ev.status = BT_HCI_ERR_MEM_CAPACITY_EXCEEDED;
+ goto done;
+ }
+
+ /* Find the next available sync handle */
+ while (queue_find(dev->le_per_adv, match_sync_handle,
+ UINT_TO_PTR(sync_handle)))
+ sync_handle++;
+
+ pa->sync_handle = sync_handle;
+
+ ev.handle = cpu_to_le16(acl->handle);
+ ev.sync_handle = cpu_to_le16(pa->sync_handle);
+ ev.sid = cpu_to_le16(pa->sid);
+ ev.addr_type = pa->addr_type;
+ memcpy(ev.addr, pa->addr, sizeof(ev.addr));
+ ev.phy = 0x01;
+ ev.interval = acl->dev->le_pa_min_interval;
+ ev.clock_accuracy = 0x07;
+
+done:
+ le_past_received_event(acl, &ev, pa);
+}
+
+static int cmd_past_set_info(struct btdev *dev, const void *data, uint8_t len)
+{
+ const struct bt_hci_cmd_le_past_set_info *cmd = data;
+ struct bt_hci_rsp_le_past_set_info rsp;
+ struct le_ext_adv *ea;
+ struct btdev_conn *acl = NULL;
+
+ memset(&rsp, 0, sizeof(rsp));
+
+ rsp.status = BT_HCI_ERR_SUCCESS;
+ rsp.handle = cmd->handle;
+
+ ea = queue_find(dev->le_ext_adv, match_ext_adv_handle,
+ UINT_TO_PTR(cmd->adv_handle));
+ if (!ea) {
+ /* If the advertising set corresponding to the
+ * Advertising_Handle parameter does not exist, the Controller
+ * shall return the error code Unknown Advertising Identifier
+ * (0x42).
+ */
+ rsp.status = BT_HCI_ERR_UNKNOWN_ADVERTISING_ID;
+ goto done;
+ }
+
+ if (!dev->le_pa_enable) {
+ /* If periodic advertising is not currently in progress for the
+ * advertising set, the Controller shall return the error code
+ * Command Disallowed (0x0C).
+ */
+ rsp.status = BT_HCI_ERR_COMMAND_DISALLOWED;
+ goto done;
+ }
+
+ acl = queue_find(dev->conns, match_handle,
+ UINT_TO_PTR(le16_to_cpu(cmd->handle)));
+ if (!acl) {
+ /* If the Connection_Handle parameter does not identify a
+ * current connection, the Controller shall return the error
+ * code Unknown Connection Identifier (0x02).
+ */
+ rsp.status = BT_HCI_ERR_UNKNOWN_CONN_ID;
+ goto done;
+ }
+
+done:
+ cmd_complete(dev, BT_HCI_CMD_LE_PAST_SET_INFO, &rsp, sizeof(rsp));
+
+ if (rsp.status == BT_HCI_ERR_SUCCESS)
+ le_past_info_received(acl->link, ea);
+
+ return 0;
+}
+
+static int cmd_past_params(struct btdev *dev, const void *data, uint8_t len)
+{
+ const struct bt_hci_cmd_le_past_params *cmd = data;
+ struct bt_hci_rsp_le_past_set_info rsp;
+ struct btdev_conn *acl = NULL;
+
+ memset(&rsp, 0, sizeof(rsp));
+
+ rsp.status = BT_HCI_ERR_SUCCESS;
+ rsp.handle = cmd->handle;
+
+ acl = queue_find(dev->conns, match_handle,
+ UINT_TO_PTR(le16_to_cpu(cmd->handle)));
+ if (!acl) {
+ /* If the Connection_Handle parameter does not identify a
+ * current connection, the Controller shall return the error
+ * code Unknown Connection Identifier (0x02).
+ */
+ rsp.status = BT_HCI_ERR_UNKNOWN_CONN_ID;
+ goto done;
+ }
+
+ acl->past_mode = cmd->mode;
+
+done:
+ cmd_complete(dev, BT_HCI_CMD_LE_PAST_PARAMS, &rsp, sizeof(rsp));
+
+ return 0;
+}
+
static int cmd_read_size_v2(struct btdev *dev, const void *data,
uint8_t len)
{
@@ -6062,19 +6336,19 @@ static int find_cig(struct btdev *dev, uint8_t cig_id)
static uint16_t make_cis_handle(uint8_t cig_idx, uint8_t cis_idx)
{
/* Put CIG+CIS idxs to handle so don't need to track separately */
- return ISO_HANDLE + cig_idx*CIS_SIZE + cis_idx;
+ return CIS_HANDLE + cig_idx*CIS_SIZE + cis_idx;
}
static int parse_cis_handle(uint16_t handle, int *cis_idx)
{
int cig_idx;
- if (handle < ISO_HANDLE || handle >= ISO_HANDLE + CIS_SIZE*CIG_SIZE)
+ if (handle < CIS_HANDLE || handle >= CIS_HANDLE + CIS_SIZE*CIG_SIZE)
return -1;
- cig_idx = (handle - ISO_HANDLE) / CIS_SIZE;
+ cig_idx = (handle - CIS_HANDLE) / CIS_SIZE;
if (cis_idx)
- *cis_idx = (handle - ISO_HANDLE) % CIS_SIZE;
+ *cis_idx = (handle - CIS_HANDLE) % CIS_SIZE;
return cig_idx;
}
@@ -6514,7 +6788,7 @@ static int cmd_create_big_complete(struct btdev *dev, const void *data,
for (i = 0; i < cmd->num_bis; i++) {
struct btdev_conn *conn;
- conn = conn_add_bis(dev, ISO_HANDLE + i, bis);
+ conn = conn_add_bis(dev, BIS_HANDLE + i, bis);
if (!conn) {
queue_remove(dev->le_big, big);
le_big_free(big);
@@ -6691,17 +6965,28 @@ static int cmd_big_create_sync_complete(struct btdev *dev, const void *data,
struct bt_hci_bis *bis;
int i;
uint16_t sync_handle = le16_to_cpu(cmd->sync_handle);
- struct le_per_adv *per_adv = queue_find(dev->le_per_adv,
- match_sync_handle, UINT_TO_PTR(sync_handle));
+ struct le_per_adv *per_adv;
struct le_big *big;
- if (!per_adv)
+ memset(&pdu.ev, 0, sizeof(pdu.ev));
+
+ per_adv = queue_find(dev->le_per_adv, match_sync_handle,
+ UINT_TO_PTR(sync_handle));
+ if (!per_adv) {
+ pdu.ev.status = BT_HCI_ERR_UNKNOWN_ADVERTISING_ID;
+ le_meta_event(dev, BT_HCI_EVT_LE_BIG_SYNC_ESTABILISHED, &pdu,
+ sizeof(pdu.ev));
return 0;
+ }
remote = find_btdev_by_bdaddr_type(per_adv->addr,
per_adv->addr_type);
- if (!remote)
+ if (!remote) {
+ pdu.ev.status = BT_HCI_ERR_UNKNOWN_ADVERTISING_ID;
+ le_meta_event(dev, BT_HCI_EVT_LE_BIG_SYNC_ESTABILISHED, &pdu,
+ sizeof(pdu.ev));
return 0;
+ }
big = le_big_new(dev, cmd->handle);
if (!big) {
@@ -6711,8 +6996,6 @@ static int cmd_big_create_sync_complete(struct btdev *dev, const void *data,
return 0;
}
- memset(&pdu.ev, 0, sizeof(pdu.ev));
-
for (i = 0; i < cmd->num_bis; i++) {
conn = conn_link_bis(dev, remote, i);
if (!conn)
@@ -6992,6 +7275,9 @@ static int cmd_config_data_path(struct btdev *dev, const void *data,
}
#define CMD_LE_52 \
+ CMD(BT_HCI_CMD_LE_PAST, cmd_past, NULL), \
+ CMD(BT_HCI_CMD_LE_PAST_SET_INFO, cmd_past_set_info, NULL), \
+ CMD(BT_HCI_CMD_LE_PAST_PARAMS, cmd_past_params, NULL), \
CMD(BT_HCI_CMD_LE_READ_BUFFER_SIZE_V2, cmd_read_size_v2, NULL), \
CMD(BT_HCI_CMD_LE_READ_ISO_TX_SYNC, cmd_read_iso_tx_sync, NULL), \
CMD(BT_HCI_CMD_LE_SET_EVENT_MASK, cmd_le_set_event_mask, NULL), \
@@ -7036,6 +7322,9 @@ static const struct btdev_cmd cmd_le_5_2[] = {
static void set_le_52_commands(struct btdev *btdev)
{
+ btdev->commands[40] |= BIT(6); /* LE PAST */
+ btdev->commands[40] |= BIT(7); /* LE PA Set Info Transfer */
+ btdev->commands[41] |= BIT(1); /* LE PAST Parameters */
btdev->commands[41] |= 0x20; /* LE Read Buffer Size v2 */
btdev->commands[41] |= 0x40; /* LE Read ISO TX Sync */
btdev->commands[41] |= 0x80; /* LE Set CIG Parameters */
@@ -7317,6 +7606,8 @@ static void set_bredrle_features(struct btdev *btdev)
if (btdev->type >= BTDEV_TYPE_BREDRLE52) {
btdev->le_features[1] |= 0x20; /* LE PER ADV */
+ btdev->le_features[3] |= BIT(0); /* LE PAST Sender */
+ btdev->le_features[3] |= BIT(1); /* LE PAST Receiver */
btdev->le_features[3] |= 0x10; /* LE CIS Central */
btdev->le_features[3] |= 0x20; /* LE CIS Peripheral */
btdev->le_features[3] |= 0x40; /* LE ISO Broadcaster */
diff --git a/emulator/bthost.c b/emulator/bthost.c
index 079f14fb3bec..79d8305d78cf 100644
--- a/emulator/bthost.c
+++ b/emulator/bthost.c
@@ -1855,6 +1855,24 @@ static void evt_le_big_sync_established(struct bthost *bthost,
}
}
+static void evt_le_big_info_adv_report(struct bthost *bthost,
+ const void *data, uint8_t size)
+{
+ const struct bt_hci_evt_le_big_info_adv_report *ev = data;
+ struct {
+ struct bt_hci_cmd_le_big_create_sync cp;
+ struct bt_hci_bis_sync index[1];
+ } cmd;
+
+ memset(&cmd, 0, sizeof(cmd));
+ cmd.cp.handle = 0x01;
+ cmd.cp.sync_handle = ev->sync_handle;
+ cmd.cp.encryption = ev->encryption;
+ cmd.cp.num_bis = 1;
+
+ send_command(bthost, BT_HCI_CMD_LE_BIG_CREATE_SYNC, &cmd, sizeof(cmd));
+}
+
static void evt_le_meta_event(struct bthost *bthost, const void *data,
uint8_t len)
{
@@ -1897,6 +1915,9 @@ static void evt_le_meta_event(struct bthost *bthost, const void *data,
case BT_HCI_EVT_LE_BIG_SYNC_ESTABILISHED:
evt_le_big_sync_established(bthost, evt_data, len - 1);
break;
+ case BT_HCI_EVT_LE_BIG_INFO_ADV_REPORT:
+ evt_le_big_info_adv_report(bthost, evt_data, len - 1);
+ break;
default:
bthost_debug(bthost, "Unsupported LE Meta event 0x%2.2x",
*event);
@@ -3715,6 +3736,28 @@ void bthost_set_pa_enable(struct bthost *bthost, uint8_t enable)
send_command(bthost, BT_HCI_CMD_LE_SET_PA_ENABLE, &cp, sizeof(cp));
}
+void bthost_set_past_mode(struct bthost *bthost, uint16_t handle, uint8_t mode)
+{
+ struct bt_hci_cmd_le_past_params cp;
+
+ memset(&cp, 0, sizeof(cp));
+ cp.handle = cpu_to_le16(handle);
+ cp.mode = mode;
+
+ send_command(bthost, BT_HCI_CMD_LE_PAST_PARAMS, &cp, sizeof(cp));
+}
+
+void bthost_past_set_info(struct bthost *bthost, uint16_t handle)
+{
+ struct bt_hci_cmd_le_past_set_info cp;
+
+ memset(&cp, 0, sizeof(cp));
+ cp.handle = cpu_to_le16(handle);
+ cp.adv_handle = 0x01;
+
+ send_command(bthost, BT_HCI_CMD_LE_PAST_SET_INFO, &cp, sizeof(cp));
+}
+
void bthost_create_big(struct bthost *bthost, uint8_t num_bis,
uint8_t enc, const uint8_t *bcode)
{
diff --git a/emulator/bthost.h b/emulator/bthost.h
index d60111d25966..4061c0be5349 100644
--- a/emulator/bthost.h
+++ b/emulator/bthost.h
@@ -122,8 +122,10 @@ void bthost_set_ext_adv_enable(struct bthost *bthost, uint8_t enable);
void bthost_set_pa_params(struct bthost *bthost);
void bthost_set_pa_data(struct bthost *bthost, const uint8_t *data,
uint8_t len);
+void bthost_set_past_mode(struct bthost *bthost, uint16_t handle, uint8_t mode);
void bthost_set_base(struct bthost *bthost, const uint8_t *data, uint8_t len);
void bthost_set_pa_enable(struct bthost *bthost, uint8_t enable);
+void bthost_past_set_info(struct bthost *bthost, uint16_t handle);
void bthost_create_big(struct bthost *bthost, uint8_t num_bis, uint8_t enc,
const uint8_t *bcode);
bool bthost_search_ext_adv_addr(struct bthost *bthost, const uint8_t *addr);
@@ -133,7 +135,6 @@ void bthost_set_cig_params(struct bthost *bthost, uint8_t cig_id,
void bthost_create_cis(struct bthost *bthost, uint16_t cis_handle,
uint16_t acl_handle);
-
void bthost_set_scan_params(struct bthost *bthost, uint8_t scan_type,
uint8_t addr_type, uint8_t filter_policy);
void bthost_set_scan_enable(struct bthost *bthost, uint8_t enable);
--
2.51.0
^ permalink raw reply related [flat|nested] 8+ messages in thread* [PATCH BlueZ v3 3/6] iso-tester: Add tests for PAST procedures
2025-10-14 20:33 [PATCH BlueZ v3 1/6] monitor: Use PAST to refer to Periodic Advertising Sync Transfer Luiz Augusto von Dentz
2025-10-14 20:33 ` [PATCH BlueZ v3 2/6] emulator: Add initial support for PAST Luiz Augusto von Dentz
@ 2025-10-14 20:33 ` Luiz Augusto von Dentz
2025-10-14 20:33 ` [PATCH BlueZ v3 4/6] monitor: Add support for PAST MGMT settings and flags Luiz Augusto von Dentz
` (4 subsequent siblings)
6 siblings, 0 replies; 8+ messages in thread
From: Luiz Augusto von Dentz @ 2025-10-14 20:33 UTC (permalink / raw)
To: linux-bluetooth
From: Luiz Augusto von Dentz <luiz.von.dentz@intel.com>
This introduces the following tests that test PAST procedures both as
a sender, either for colocated broadcast source or a third peer, and as
receiver:
ISO Broadcaster PAST Info - Success
ISO Broadcaster PAST Info RPA - Success
ISO Broadcaster PAST Sender - Success
ISO Broadcaster PAST Receiver - Success
---
tools/iso-tester.c | 292 +++++++++++++++++++++++++++++++++++++++++++--
1 file changed, 279 insertions(+), 13 deletions(-)
diff --git a/tools/iso-tester.c b/tools/iso-tester.c
index 0eeab4fd7108..4bf1a287bc68 100644
--- a/tools/iso-tester.c
+++ b/tools/iso-tester.c
@@ -488,6 +488,8 @@ struct iso_client_data {
const struct iovec *recv;
bool server;
bool bcast;
+ bool past;
+ bool rpa;
bool defer;
bool disconnect;
bool ts;
@@ -1381,6 +1383,28 @@ static const struct iso_client_data bcast_16_2_1_send = {
.base_len = sizeof(base_lc3_16_2_1),
};
+static const struct iso_client_data past_16_2_1_send = {
+ .qos = QOS_OUT_16_2_1,
+ .expect_err = 0,
+ .send = &send_16_2_1,
+ .bcast = true,
+ .past = true,
+ .rpa = true,
+ .base = base_lc3_16_2_1,
+ .base_len = sizeof(base_lc3_16_2_1),
+};
+
+static const struct iso_client_data past_16_2_1 = {
+ .qos = QOS_OUT_16_2_1,
+ .expect_err = 0,
+ .recv = &send_16_2_1,
+ .bcast = true,
+ .past = true,
+ .big = true,
+ .base = base_lc3_16_2_1,
+ .base_len = sizeof(base_lc3_16_2_1),
+};
+
static const struct iso_client_data bcast_enc_16_2_1_send = {
.qos = QOS_OUT_ENC_16_2_1,
.expect_err = 0,
@@ -1446,6 +1470,16 @@ static const struct iso_client_data bcast_16_2_1_recv = {
.big = true,
};
+static const struct iso_client_data past_16_2_1_recv = {
+ .qos = QOS_IN_16_2_1,
+ .expect_err = 0,
+ .recv = &send_16_2_1,
+ .bcast = true,
+ .past = true,
+ .server = true,
+ .big = true,
+};
+
static const struct iso_client_data bcast_16_2_1_recv2 = {
.qos = QOS_IN_16_2_1,
.expect_err = 0,
@@ -1594,6 +1628,7 @@ static void client_connectable_complete(uint16_t opcode, uint8_t status,
{
struct test_data *data = user_data;
static uint8_t client_num;
+ const struct iso_client_data *isodata = data->test_data;
if (opcode != BT_HCI_CMD_LE_SET_EXT_ADV_ENABLE)
return;
@@ -1606,7 +1641,8 @@ static void client_connectable_complete(uint16_t opcode, uint8_t status,
if (status)
tester_setup_failed();
else if (data->client_num == client_num) {
- tester_setup_complete();
+ if (!isodata || !isodata->past)
+ tester_setup_complete();
client_num = 0;
}
}
@@ -1641,6 +1677,8 @@ static void iso_new_conn(uint16_t handle, void *user_data)
{
struct test_data *data = user_data;
struct bthost *host;
+ const struct iso_client_data *isodata = data->test_data;
+ static uint8_t client_num;
tester_print("New client connection with handle 0x%04x", handle);
@@ -1649,6 +1687,14 @@ static void iso_new_conn(uint16_t handle, void *user_data)
host = hciemu_client_get_host(data->hciemu);
bthost_add_iso_hook(host, data->handle, bthost_recv_data, data,
bthost_iso_disconnected);
+
+ if (!isodata->past || data->client_num == 1)
+ return;
+
+ client_num++;
+
+ if (client_num == data->client_num)
+ tester_test_passed();
}
static uint8_t iso_accept_conn(uint16_t handle, void *user_data)
@@ -1664,10 +1710,73 @@ static uint8_t iso_accept_conn(uint16_t handle, void *user_data)
static void acl_new_conn(uint16_t handle, void *user_data)
{
struct test_data *data = user_data;
+ const struct iso_client_data *isodata = data->test_data;
tester_print("New ACL connection with handle 0x%04x", handle);
data->acl_handle = handle;
+
+ if (!isodata->past)
+ return;
+
+ tester_setup_complete();
+
+ if (!isodata->server) {
+ struct bthost *host;
+
+ host = hciemu_client_get_host(data->hciemu);
+ bthost_set_past_mode(host, data->acl_handle, 0x03);
+ }
+}
+
+static void setup_connect_recv(struct test_data *data, struct bthost *host)
+{
+ const uint8_t *bdaddr;
+
+ bdaddr = hciemu_get_central_bdaddr(data->hciemu);
+ bthost_set_connect_cb(host, acl_new_conn, data);
+ bthost_hci_connect(host, bdaddr, BDADDR_LE_PUBLIC);
+}
+
+static void setup_past_complete(uint8_t status, uint16_t length,
+ const void *param, void *user_data)
+{
+ struct test_data *data = tester_get_data();
+ struct bthost *host = user_data;
+
+ if (status != MGMT_STATUS_SUCCESS) {
+ tester_setup_failed();
+ return;
+ }
+
+ tester_print("Set device flags status 0x%02x", status);
+
+ setup_connect_recv(data, host);
+}
+
+static void setup_past_recv(struct test_data *data, struct bthost *host)
+{
+ struct mgmt_cp_add_device add;
+ struct mgmt_cp_set_device_flags set;
+
+ memset(&add, 0, sizeof(add));
+ bacpy(&add.addr.bdaddr,
+ (bdaddr_t *)hciemu_get_client_bdaddr(data->hciemu));
+ add.addr.type = BDADDR_LE_PUBLIC;
+ add.action = 0x01; /* Allow incoming connection */
+
+ mgmt_send(data->mgmt, MGMT_OP_ADD_DEVICE, data->mgmt_index,
+ sizeof(add), &add, NULL, NULL, NULL);
+
+ memset(&set, 0, sizeof(set));
+ bacpy(&set.addr.bdaddr,
+ (bdaddr_t *)hciemu_get_client_bdaddr(data->hciemu));
+ set.addr.type = BDADDR_LE_PUBLIC;
+ set.current_flags = BIT(3);
+
+ mgmt_send(data->mgmt, MGMT_OP_SET_DEVICE_FLAGS, data->mgmt_index,
+ sizeof(set), &set, setup_past_complete, host,
+ NULL);
}
static void setup_powered_callback(uint8_t status, uint16_t length,
@@ -1716,18 +1825,17 @@ static void setup_powered_callback(uint8_t status, uint16_t length,
bthost_set_base(host, isodata->base,
isodata->base_len);
- if (isodata->big)
+ if (isodata->big && (!isodata->past ||
+ i + 1 == data->client_num))
bthost_create_big(host, 1,
isodata->qos.bcast.encryption,
isodata->qos.bcast.bcode);
- } else if (!isodata->send && isodata->recv) {
- const uint8_t *bdaddr;
+ if (isodata->past)
+ setup_past_recv(data, host);
- bdaddr = hciemu_get_central_bdaddr(data->hciemu);
- bthost_set_connect_cb(host, acl_new_conn, data);
- bthost_hci_connect(host, bdaddr, BDADDR_LE_PUBLIC);
- }
+ } else if (!isodata->send && isodata->recv)
+ setup_connect_recv(data, host);
}
}
@@ -1739,7 +1847,7 @@ static void setup_powered(const void *test_data)
tester_print("Powering on controller");
- if (!isodata || !isodata->bcast)
+ if (!isodata || !isodata->bcast || isodata->past)
mgmt_send(data->mgmt, MGMT_OP_SET_CONNECTABLE, data->mgmt_index,
sizeof(param), param,
NULL, NULL, NULL);
@@ -1750,7 +1858,16 @@ static void setup_powered(const void *test_data)
mgmt_send(data->mgmt, MGMT_OP_SET_LE, data->mgmt_index,
sizeof(param), param, NULL, NULL, NULL);
- if (isodata && isodata->server && !isodata->bcast)
+ if (isodata && isodata->rpa) {
+ const uint8_t params[] = { 0x01,
+ 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08,
+ 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08 };
+
+ mgmt_send(data->mgmt, MGMT_OP_SET_PRIVACY, data->mgmt_index,
+ sizeof(params), params, NULL, NULL, NULL);
+ }
+
+ if (isodata && ((isodata->server && !isodata->bcast) || isodata->past))
mgmt_send(data->mgmt, MGMT_OP_SET_ADVERTISING,
data->mgmt_index, sizeof(param), param, NULL,
NULL, NULL);
@@ -1905,6 +2022,7 @@ static int create_iso_sock(struct test_data *data)
addr->iso_bc->bc_sid = isodata->sid;
err = bind(sk, (struct sockaddr *) addr, sizeof(*addr) +
sizeof(*addr->iso_bc));
+ free(addr);
} else {
addr = malloc(sizeof(*addr));
memset(addr, 0, sizeof(*addr));
@@ -1912,6 +2030,7 @@ static int create_iso_sock(struct test_data *data)
bacpy(&addr->iso_bdaddr, (void *) master_bdaddr);
addr->iso_bdaddr_type = BDADDR_LE_PUBLIC;
err = bind(sk, (struct sockaddr *) addr, sizeof(*addr));
+ free(addr);
}
if (err < 0) {
@@ -2520,6 +2639,9 @@ static gboolean iso_pollout(GIOChannel *io, GIOCondition cond,
const struct iso_client_data *isodata = data->test_data;
unsigned int count;
+ if (isodata->past && !data->handle)
+ return TRUE;
+
data->io_id[0] = 0;
tester_print("POLLOUT event received");
@@ -2533,6 +2655,8 @@ static gboolean iso_pollout(GIOChannel *io, GIOCondition cond,
iso_send_data(data, io);
if (isodata->bcast) {
+ if (isodata->past)
+ return FALSE;
tester_test_passed();
return FALSE;
}
@@ -2588,6 +2712,84 @@ static void trigger_force_suspend(void *user_data)
hook_set_event_mask, data);
}
+static int iso_rebind_bcast_dst(struct test_data *data, int sk)
+{
+ struct hciemu_client *client;
+ const uint8_t *dst;
+ struct sockaddr_iso *addr = NULL;
+ int err;
+
+ client = hciemu_get_client(data->hciemu, 0);
+
+ /* Bind to local address */
+ addr = malloc(sizeof(*addr) + sizeof(*addr->iso_bc));
+ memset(addr, 0, sizeof(*addr) + sizeof(*addr->iso_bc));
+ addr->iso_family = AF_BLUETOOTH;
+
+ /* Bind to destination address in case of broadcast */
+ dst = hciemu_client_bdaddr(client);
+ if (!dst) {
+ tester_warn("No destination bdaddr");
+ free(addr);
+ return -ENODEV;
+ }
+
+ bacpy(&addr->iso_bc->bc_bdaddr, (void *) dst);
+ addr->iso_bc->bc_bdaddr_type = BDADDR_LE_PUBLIC;
+
+ err = bind(sk, (struct sockaddr *) addr, sizeof(*addr) +
+ sizeof(*addr->iso_bc));
+ if (err)
+ tester_warn("bind: %s (%d)", strerror(errno), errno);
+ else
+ tester_print("PAST in progress...");
+
+ free(addr);
+
+ return err;
+}
+
+static bool check_rpa(struct test_data *data, int sk)
+{
+ const struct iso_client_data *isodata = data->test_data;
+ struct sockaddr_iso addr;
+ socklen_t olen;
+ const uint8_t *src;
+
+ if (!isodata->rpa)
+ return true;
+
+ src = hciemu_get_central_bdaddr(data->hciemu);
+ if (!src) {
+ tester_warn("No source bdaddr");
+ return false;
+ }
+
+ olen = sizeof(addr);
+
+ memset(&addr, 0, olen);
+ if (getsockname(sk, (void *)&addr, &olen) < 0) {
+ tester_warn("getsockname: %s (%d)", strerror(errno), errno);
+ return false;
+ }
+
+ /* Compare socket source address (RPA) with central address, if they
+ * match it means the RPA has not been set.
+ */
+ if (!bacmp(&addr.iso_bdaddr, (bdaddr_t *)src)) {
+ char a1[18], a2[18];
+
+ ba2str(&addr.iso_bdaddr, a1);
+ ba2str((bdaddr_t *)src, a2);
+
+ tester_warn("rpa %s == %s id", a1, a2);
+ return false;
+
+ }
+
+ return true;
+}
+
static gboolean iso_connect(GIOChannel *io, GIOCondition cond,
gpointer user_data)
{
@@ -2616,8 +2818,11 @@ static gboolean iso_connect(GIOChannel *io, GIOCondition cond,
if (!isodata->bcast) {
ret = check_ucast_qos(&qos, &isodata->qos,
isodata->mconn ? &isodata->qos_2 : NULL);
- } else if (!isodata->server)
+ } else if (!isodata->server) {
ret = check_bcast_qos(&qos, &isodata->qos);
+ if (ret && isodata->past)
+ ret = iso_rebind_bcast_dst(data, sk) == 0;
+ }
if (!ret) {
tester_warn("Unexpected QoS parameter");
@@ -2692,8 +2897,15 @@ static gboolean iso_connect(GIOChannel *io, GIOCondition cond,
if (err < 0)
tester_warn("Connect failed: %s (%d)", strerror(-err), -err);
- else
+ else {
+ if (!check_rpa(data, sk)) {
+ data->step = 0;
+ tester_test_failed();
+ return FALSE;
+ }
+
tester_print("Successfully connected");
+ }
if (err != isodata->expect_err) {
tester_warn("Expect error: %s (%d) != %s (%d)",
@@ -3025,6 +3237,17 @@ fail:
return err;
}
+static gboolean test_listen_past(gpointer user_data)
+{
+ struct test_data *data = tester_get_data();
+ struct bthost *host;
+
+ host = hciemu_client_get_host(data->hciemu);
+ bthost_past_set_info(host, data->acl_handle);
+
+ return FALSE;
+}
+
static void setup_listen_many(struct test_data *data, uint8_t n, uint8_t *num,
GIOFunc *func)
{
@@ -3070,7 +3293,18 @@ static void setup_listen_many(struct test_data *data, uint8_t n, uint8_t *num,
host = hciemu_client_host(client);
bthost_set_cig_params(host, 0x01, 0x01, &isodata->qos);
- bthost_create_cis(host, 257, data->acl_handle);
+ bthost_create_cis(host, 256, data->acl_handle);
+ } else if (isodata->past) {
+ if (!data->acl_handle) {
+ tester_print("ACL handle not set");
+ tester_test_failed();
+ return;
+ }
+
+ /* Wait for listen to take effect before initiating PAST
+ * procedure.
+ */
+ data->io_id[i] = g_timeout_add(250, test_listen_past, data);
}
}
@@ -3518,6 +3752,18 @@ static void test_bcast(const void *test_data)
setup_connect(data, 0, iso_connect_cb);
}
+static void test_past(const void *test_data)
+{
+ struct test_data *data = tester_get_data();
+ uint8_t num[1] = { 1 };
+ GIOFunc funcs[1] = { iso_accept2_cb };
+
+ if (data->client_num > 1)
+ setup_listen_many(data, 1, num, funcs);
+ else
+ setup_connect(data, 0, iso_connect_cb);
+}
+
static void test_bcast_reconnect(const void *test_data)
{
struct test_data *data = tester_get_data();
@@ -3593,6 +3839,13 @@ static void test_bcast_recv2_defer(const void *test_data)
setup_listen_many(data, 2, num, funcs);
}
+static void test_past_recv(const void *test_data)
+{
+ struct test_data *data = tester_get_data();
+
+ setup_listen(data, 0, iso_accept_cb);
+}
+
static void test_connect2_suspend(const void *test_data)
{
test_connect2(test_data);
@@ -3980,6 +4233,15 @@ int main(int argc, char *argv[])
test_iso("ISO Broadcaster - Success", &bcast_16_2_1_send, setup_powered,
test_bcast);
+ test_iso("ISO Broadcaster PAST Info - Success", &past_16_2_1_send,
+ setup_powered,
+ test_past);
+ test_iso("ISO Broadcaster PAST Info RPA - Success", &past_16_2_1_send,
+ setup_powered,
+ test_past);
+ test_iso2("ISO Broadcaster PAST Sender - Success", &past_16_2_1,
+ setup_powered,
+ test_past);
test_iso("ISO Broadcaster Encrypted - Success", &bcast_enc_16_2_1_send,
setup_powered,
test_bcast);
@@ -4003,6 +4265,10 @@ int main(int argc, char *argv[])
test_iso("ISO Broadcaster Receiver - Success", &bcast_16_2_1_recv,
setup_powered,
test_bcast_recv);
+ test_iso("ISO Broadcaster PAST Receiver - Success",
+ &past_16_2_1_recv,
+ setup_powered,
+ test_past_recv);
test_iso("ISO Broadcaster Receiver SID auto - Success",
&bcast_16_2_1_recv_sid,
setup_powered,
--
2.51.0
^ permalink raw reply related [flat|nested] 8+ messages in thread* [PATCH BlueZ v3 4/6] monitor: Add support for PAST MGMT settings and flags
2025-10-14 20:33 [PATCH BlueZ v3 1/6] monitor: Use PAST to refer to Periodic Advertising Sync Transfer Luiz Augusto von Dentz
2025-10-14 20:33 ` [PATCH BlueZ v3 2/6] emulator: Add initial support for PAST Luiz Augusto von Dentz
2025-10-14 20:33 ` [PATCH BlueZ v3 3/6] iso-tester: Add tests for PAST procedures Luiz Augusto von Dentz
@ 2025-10-14 20:33 ` Luiz Augusto von Dentz
2025-10-14 20:33 ` [PATCH BlueZ v3 5/6] MGMT: Add PAST Settings and Flags Luiz Augusto von Dentz
` (3 subsequent siblings)
6 siblings, 0 replies; 8+ messages in thread
From: Luiz Augusto von Dentz @ 2025-10-14 20:33 UTC (permalink / raw)
To: linux-bluetooth
From: Luiz Augusto von Dentz <luiz.von.dentz@intel.com>
This adds parising support for PAST MGMT settings and device flags.
---
monitor/packet.c | 3 +++
1 file changed, 3 insertions(+)
diff --git a/monitor/packet.c b/monitor/packet.c
index f7db1cbb88c6..dd808deaa79f 100644
--- a/monitor/packet.c
+++ b/monitor/packet.c
@@ -14424,6 +14424,8 @@ static const struct bitfield_data mgmt_settings_table[] = {
{ 20, "ISO Broadcaster" },
{ 21, "Sync Receiver" },
{ 22, "LL Privacy" },
+ { 23, "PAST Sender" },
+ { 24, "PAST Receiver" },
{}
};
@@ -15852,6 +15854,7 @@ static const struct bitfield_data mgmt_added_device_flags_table[] = {
{ 0, "Remote Wakeup" },
{ 1, "Device Privacy Mode" },
{ 2, "Address Resolution" },
+ { 3, "PAST" },
{ }
};
--
2.51.0
^ permalink raw reply related [flat|nested] 8+ messages in thread* [PATCH BlueZ v3 5/6] MGMT: Add PAST Settings and Flags
2025-10-14 20:33 [PATCH BlueZ v3 1/6] monitor: Use PAST to refer to Periodic Advertising Sync Transfer Luiz Augusto von Dentz
` (2 preceding siblings ...)
2025-10-14 20:33 ` [PATCH BlueZ v3 4/6] monitor: Add support for PAST MGMT settings and flags Luiz Augusto von Dentz
@ 2025-10-14 20:33 ` Luiz Augusto von Dentz
2025-10-14 20:34 ` [PATCH BlueZ v3 6/6] iso.rst: Add documentation for PAST/rebind Luiz Augusto von Dentz
` (2 subsequent siblings)
6 siblings, 0 replies; 8+ messages in thread
From: Luiz Augusto von Dentz @ 2025-10-14 20:33 UTC (permalink / raw)
To: linux-bluetooth
From: Luiz Augusto von Dentz <luiz.von.dentz@intel.com>
This adds PAST Settings and Flags definitions and documentation.
---
doc/mgmt.rst | 3 +++
lib/bluetooth/mgmt.h | 3 +++
2 files changed, 6 insertions(+)
diff --git a/doc/mgmt.rst b/doc/mgmt.rst
index 5ffc766bddc4..3fca69ed0b6e 100644
--- a/doc/mgmt.rst
+++ b/doc/mgmt.rst
@@ -319,6 +319,8 @@ following available bits:
20, Isochronous Broadcaster
21, Synchronized Receiver
22, LL Privacy
+ 23, PAST Sender
+ 24, PAST Receiver
This command generates a Command Complete event on success or a Command Status
event on failure.
@@ -3581,6 +3583,7 @@ available bits:
0, Remote Wakeup enabled
1, Device Privacy Mode enabled
2, Address Resolution enabled
+ 3, PAST enabled
This command generates a Command Complete event on success or a Command Status
event on failure.
diff --git a/lib/bluetooth/mgmt.h b/lib/bluetooth/mgmt.h
index 2b45010d1b0b..1ad52529f0c7 100644
--- a/lib/bluetooth/mgmt.h
+++ b/lib/bluetooth/mgmt.h
@@ -105,6 +105,8 @@ struct mgmt_rp_read_index_list {
#define MGMT_SETTING_ISO_BROADCASTER BIT(20)
#define MGMT_SETTING_ISO_SYNC_RECEIVER BIT(21)
#define MGMT_SETTING_LL_PRIVACY BIT(22)
+#define MGMT_SETTING_PAST_SENDER BIT(23)
+#define MGMT_SETTING_PAST_RECEIVER BIT(24)
#define MGMT_OP_READ_INFO 0x0004
struct mgmt_rp_read_info {
@@ -680,6 +682,7 @@ struct mgmt_rp_get_device_flags {
#define DEVICE_FLAG_REMOTE_WAKEUP BIT(0)
#define DEVICE_FLAG_DEVICE_PRIVACY BIT(1)
#define DEVICE_FLAG_ADDRESS_RESOLUTION BIT(2)
+#define DEVICE_FLAG_PAST BIT(3)
#define MGMT_OP_SET_DEVICE_FLAGS 0x0050
#define MGMT_SET_DEVICE_FLAGS_SIZE 11
--
2.51.0
^ permalink raw reply related [flat|nested] 8+ messages in thread* [PATCH BlueZ v3 6/6] iso.rst: Add documentation for PAST/rebind
2025-10-14 20:33 [PATCH BlueZ v3 1/6] monitor: Use PAST to refer to Periodic Advertising Sync Transfer Luiz Augusto von Dentz
` (3 preceding siblings ...)
2025-10-14 20:33 ` [PATCH BlueZ v3 5/6] MGMT: Add PAST Settings and Flags Luiz Augusto von Dentz
@ 2025-10-14 20:34 ` Luiz Augusto von Dentz
2025-10-14 22:13 ` [BlueZ,v3,1/6] monitor: Use PAST to refer to Periodic Advertising Sync Transfer bluez.test.bot
2025-10-14 22:30 ` [PATCH BlueZ v3 1/6] " patchwork-bot+bluetooth
6 siblings, 0 replies; 8+ messages in thread
From: Luiz Augusto von Dentz @ 2025-10-14 20:34 UTC (permalink / raw)
To: linux-bluetooth
From: Luiz Augusto von Dentz <luiz.von.dentz@intel.com>
This documents how to use PAST procedures by doing bind on already
connected socket.
---
doc/iso.rst | 20 ++++++++++++++++++++
1 file changed, 20 insertions(+)
diff --git a/doc/iso.rst b/doc/iso.rst
index 2ad9c73e4eb8..4d315132f911 100644
--- a/doc/iso.rst
+++ b/doc/iso.rst
@@ -125,6 +125,26 @@ Broadcast Sink (Receiver) example:
/* Bind to Broadcaster address */
bind(iso_socket, (struct sockaddr *)addr, addr_len);
+Broadcast Source (Broadcaster) or Broadcast Sink (Receiver) Periodic
+Advertising Sync Transfer (PAST):
+
+.. code-block::
+
+ struct sockaddr_iso *addr;
+ size_t addr_len;
+
+ addr_len = sizeof(*addr) + sizeof(*addr->iso_bc);
+
+ memset(addr, 0, addr_len);
+ addr->iso_family = AF_BLUETOOTH;
+
+ /* Set destination address to PAST destination address */
+ bacpy(&addr->iso_bc->bc_bdaddr, (void *) bdaddr);
+ addr->iso_bc->bc_bdaddr_type = bdaddr_type;
+
+ /* Rebind already connected socket to PAST address */
+ bind(iso_socket, (struct sockaddr *)addr, addr_len);
+
SOCKET OPTIONS (SOL_BLUETOOTH)
==============================
--
2.51.0
^ permalink raw reply related [flat|nested] 8+ messages in thread* RE: [BlueZ,v3,1/6] monitor: Use PAST to refer to Periodic Advertising Sync Transfer
2025-10-14 20:33 [PATCH BlueZ v3 1/6] monitor: Use PAST to refer to Periodic Advertising Sync Transfer Luiz Augusto von Dentz
` (4 preceding siblings ...)
2025-10-14 20:34 ` [PATCH BlueZ v3 6/6] iso.rst: Add documentation for PAST/rebind Luiz Augusto von Dentz
@ 2025-10-14 22:13 ` bluez.test.bot
2025-10-14 22:30 ` [PATCH BlueZ v3 1/6] " patchwork-bot+bluetooth
6 siblings, 0 replies; 8+ messages in thread
From: bluez.test.bot @ 2025-10-14 22:13 UTC (permalink / raw)
To: linux-bluetooth, luiz.dentz
[-- Attachment #1: Type: text/plain, Size: 2293 bytes --]
This is automated email and please do not reply to this email!
Dear submitter,
Thank you for submitting the patches to the linux bluetooth mailing list.
This is a CI test results with your patch series:
PW Link:https://patchwork.kernel.org/project/bluetooth/list/?series=1011519
---Test result---
Test Summary:
CheckPatch PENDING 0.36 seconds
GitLint PENDING 0.36 seconds
BuildEll PASS 19.82 seconds
BluezMake PASS 2686.46 seconds
MakeCheck PASS 20.51 seconds
MakeDistcheck PASS 183.32 seconds
CheckValgrind PASS 234.30 seconds
CheckSmatch WARNING 306.32 seconds
bluezmakeextell PASS 127.19 seconds
IncrementalBuild PENDING 0.34 seconds
ScanBuild PASS 908.52 seconds
Details
##############################
Test: CheckPatch - PENDING
Desc: Run checkpatch.pl script
Output:
##############################
Test: GitLint - PENDING
Desc: Run gitlint
Output:
##############################
Test: CheckSmatch - WARNING
Desc: Run smatch tool with source
Output:
monitor/packet.c: note: in included file:monitor/display.h:82:26: warning: Variable length array is used.monitor/packet.c:1931:26: warning: Variable length array is used.monitor/packet.c: note: in included file:monitor/bt.h:3837:52: warning: array of flexible structuresemulator/btdev.c:459:29: warning: Variable length array is used.emulator/bthost.c:699:28: warning: Variable length array is used.emulator/bthost.c:700:32: warning: Variable length array is used.emulator/bthost.c:917:28: warning: Variable length array is used.emulator/bthost.c:951:28: warning: Variable length array is used.emulator/bthost.c:952:32: warning: Variable length array is used.monitor/packet.c: note: in included file:monitor/display.h:82:26: warning: Variable length array is used.monitor/packet.c:1931:26: warning: Variable length array is used.monitor/packet.c: note: in included file:monitor/bt.h:3837:52: warning: array of flexible structures
##############################
Test: IncrementalBuild - PENDING
Desc: Incremental build with the patches in the series
Output:
---
Regards,
Linux Bluetooth
^ permalink raw reply [flat|nested] 8+ messages in thread* Re: [PATCH BlueZ v3 1/6] monitor: Use PAST to refer to Periodic Advertising Sync Transfer
2025-10-14 20:33 [PATCH BlueZ v3 1/6] monitor: Use PAST to refer to Periodic Advertising Sync Transfer Luiz Augusto von Dentz
` (5 preceding siblings ...)
2025-10-14 22:13 ` [BlueZ,v3,1/6] monitor: Use PAST to refer to Periodic Advertising Sync Transfer bluez.test.bot
@ 2025-10-14 22:30 ` patchwork-bot+bluetooth
6 siblings, 0 replies; 8+ messages in thread
From: patchwork-bot+bluetooth @ 2025-10-14 22:30 UTC (permalink / raw)
To: Luiz Augusto von Dentz; +Cc: linux-bluetooth
Hello:
This series was applied to bluetooth/bluez.git (master)
by Luiz Augusto von Dentz <luiz.von.dentz@intel.com>:
On Tue, 14 Oct 2025 16:33:55 -0400 you wrote:
> From: Luiz Augusto von Dentz <luiz.von.dentz@intel.com>
>
> This simplify the command and event names and their structs to just
> use PAST in place of other terminology currently in use.
> ---
> monitor/bt.h | 39 +++++++++++++++++++++++++++------------
> monitor/packet.c | 41 +++++++++++++++++++++++------------------
> 2 files changed, 50 insertions(+), 30 deletions(-)
Here is the summary with links:
- [BlueZ,v3,1/6] monitor: Use PAST to refer to Periodic Advertising Sync Transfer
https://git.kernel.org/pub/scm/bluetooth/bluez.git/?id=620c5b4af4fd
- [BlueZ,v3,2/6] emulator: Add initial support for PAST
https://git.kernel.org/pub/scm/bluetooth/bluez.git/?id=8656f1aa1556
- [BlueZ,v3,3/6] iso-tester: Add tests for PAST procedures
https://git.kernel.org/pub/scm/bluetooth/bluez.git/?id=d4811ecbcef6
- [BlueZ,v3,4/6] monitor: Add support for PAST MGMT settings and flags
https://git.kernel.org/pub/scm/bluetooth/bluez.git/?id=a6974c55c0c4
- [BlueZ,v3,5/6] MGMT: Add PAST Settings and Flags
https://git.kernel.org/pub/scm/bluetooth/bluez.git/?id=5c53260bd5c4
- [BlueZ,v3,6/6] iso.rst: Add documentation for PAST/rebind
https://git.kernel.org/pub/scm/bluetooth/bluez.git/?id=025d2ef81245
You are awesome, thank you!
--
Deet-doot-dot, I am a bot.
https://korg.docs.kernel.org/patchwork/pwbot.html
^ permalink raw reply [flat|nested] 8+ messages in thread