Message ID | e26c5c8ef755e9dbe2e1a5204a86ecd907fd6508.1746280854.git.pav@iki.fi |
---|---|
State | Accepted |
Commit | f3daca9b490154fbb0459848cc2ed61e8367bddc |
Headers | show |
Series | Bluetooth: separate ISO_LINK_UCAST and BCAST link types | expand |
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=959334 ---Test result--- Test Summary: CheckPatch PENDING 0.24 seconds GitLint PENDING 0.24 seconds SubjectPrefix PASS 0.12 seconds BuildKernel PASS 24.05 seconds CheckAllWarning PASS 26.67 seconds CheckSparse WARNING 30.19 seconds BuildKernel32 PASS 23.91 seconds TestRunnerSetup PASS 453.53 seconds TestRunner_l2cap-tester PASS 22.11 seconds TestRunner_iso-tester PASS 30.49 seconds TestRunner_bnep-tester PASS 4.74 seconds TestRunner_mgmt-tester FAIL 116.81 seconds TestRunner_rfcomm-tester PASS 7.81 seconds TestRunner_sco-tester PASS 13.10 seconds TestRunner_ioctl-tester PASS 8.27 seconds TestRunner_mesh-tester FAIL 6.27 seconds TestRunner_smp-tester PASS 8.14 seconds TestRunner_userchan-tester PASS 4.96 seconds IncrementalBuild PENDING 0.64 seconds Details ############################## Test: CheckPatch - PENDING Desc: Run checkpatch.pl script Output: ############################## Test: GitLint - PENDING Desc: Run gitlint Output: ############################## Test: CheckSparse - WARNING Desc: Run sparse tool with linux kernel Output: net/bluetooth/hci_event.c: note: in included file (through include/net/bluetooth/hci_core.h): ############################## Test: TestRunner_mgmt-tester - FAIL Desc: Run mgmt-tester with test-runner Output: Total: 490, Passed: 485 (99.0%), Failed: 1, Not Run: 4 Failed Test Cases LL Privacy - Set Device Flag 1 (Device Privacy) Failed 0.158 seconds ############################## Test: TestRunner_mesh-tester - FAIL Desc: Run mesh-tester with test-runner Output: Total: 10, Passed: 9 (90.0%), Failed: 1, Not Run: 0 Failed Test Cases Mesh - Send cancel - 2 Failed 0.114 seconds ############################## Test: IncrementalBuild - PENDING Desc: Incremental build with the patches in the series Output: --- Regards, Linux Bluetooth
Hi Pauli, On Sat, May 3, 2025 at 10:08 AM Pauli Virtanen <pav@iki.fi> wrote: > > Use separate link type id for unicast and broadcast ISO connections. > These connection types are handled with separate HCI commands, socket > API is different, and hci_conn has union fields that are different in > the two cases, so they shall not be mixed up. > > Currently in most places it is attempted to distinguish ucast by > bacmp(&c->dst, BDADDR_ANY) but it is wrong as dst is set for bcast sink > hci_conn in iso_conn_ready(). Additionally checking sync_handle might be > OK, but depends on details of bcast conn configuration flow. > > To avoid complicating it, use separate link types. While I agree this makes things easier, I'd go with CIS_LINK and BIS_LINK as names, anyway I can probably rename it myself so no need to resend. > Fixes: f764a6c2c1e4 ("Bluetooth: ISO: Add broadcast support") > Signed-off-by: Pauli Virtanen <pav@iki.fi> > --- > > Notes: > Although in theory this should be OK, bcast functionality is untested > with this patch, aside from passing iso-tester. > > include/net/bluetooth/hci.h | 3 +- > include/net/bluetooth/hci_core.h | 48 ++++++++++++++------------------ > net/bluetooth/hci_conn.c | 44 +++++++++++++++++------------ > net/bluetooth/hci_core.c | 21 ++++++++------ > net/bluetooth/hci_event.c | 24 ++++++++-------- > net/bluetooth/hci_sync.c | 16 +++++++---- > net/bluetooth/iso.c | 4 +-- > net/bluetooth/mgmt.c | 3 +- > 8 files changed, 89 insertions(+), 74 deletions(-) > > diff --git a/include/net/bluetooth/hci.h b/include/net/bluetooth/hci.h > index 2502febf4da7..4d19fde81770 100644 > --- a/include/net/bluetooth/hci.h > +++ b/include/net/bluetooth/hci.h > @@ -558,7 +558,8 @@ enum { > #define ESCO_LINK 0x02 > /* Low Energy links do not have defined link type. Use invented one */ > #define LE_LINK 0x80 > -#define ISO_LINK 0x82 > +#define ISO_LINK_UCAST 0x82 > +#define ISO_LINK_BCAST 0x83 > #define INVALID_LINK 0xff > > /* LMP features */ > diff --git a/include/net/bluetooth/hci_core.h b/include/net/bluetooth/hci_core.h > index 965ca1ca841c..7f89a19ca1d9 100644 > --- a/include/net/bluetooth/hci_core.h > +++ b/include/net/bluetooth/hci_core.h > @@ -999,7 +999,8 @@ static inline void hci_conn_hash_add(struct hci_dev *hdev, struct hci_conn *c) > case ESCO_LINK: > h->sco_num++; > break; > - case ISO_LINK: > + case ISO_LINK_UCAST: > + case ISO_LINK_BCAST: > h->iso_num++; > break; > } > @@ -1025,7 +1026,8 @@ static inline void hci_conn_hash_del(struct hci_dev *hdev, struct hci_conn *c) > case ESCO_LINK: > h->sco_num--; > break; > - case ISO_LINK: > + case ISO_LINK_UCAST: > + case ISO_LINK_BCAST: > h->iso_num--; > break; > } > @@ -1042,7 +1044,8 @@ static inline unsigned int hci_conn_num(struct hci_dev *hdev, __u8 type) > case SCO_LINK: > case ESCO_LINK: > return h->sco_num; > - case ISO_LINK: > + case ISO_LINK_UCAST: > + case ISO_LINK_BCAST: > return h->iso_num; > default: > return 0; > @@ -1103,7 +1106,7 @@ static inline struct hci_conn *hci_conn_hash_lookup_bis(struct hci_dev *hdev, > rcu_read_lock(); > > list_for_each_entry_rcu(c, &h->list, list) { > - if (bacmp(&c->dst, ba) || c->type != ISO_LINK) > + if (bacmp(&c->dst, ba) || c->type != ISO_LINK_BCAST) > continue; > > if (c->iso_qos.bcast.bis == bis) { > @@ -1125,7 +1128,7 @@ hci_conn_hash_lookup_create_pa_sync(struct hci_dev *hdev) > rcu_read_lock(); > > list_for_each_entry_rcu(c, &h->list, list) { > - if (c->type != ISO_LINK) > + if (c->type != ISO_LINK_BCAST) > continue; > > if (!test_bit(HCI_CONN_CREATE_PA_SYNC, &c->flags)) > @@ -1151,8 +1154,8 @@ hci_conn_hash_lookup_per_adv_bis(struct hci_dev *hdev, > rcu_read_lock(); > > list_for_each_entry_rcu(c, &h->list, list) { > - if (bacmp(&c->dst, ba) || c->type != ISO_LINK || > - !test_bit(HCI_CONN_PER_ADV, &c->flags)) > + if (bacmp(&c->dst, ba) || c->type != ISO_LINK_BCAST || > + !test_bit(HCI_CONN_PER_ADV, &c->flags)) > continue; > > if (c->iso_qos.bcast.big == big && > @@ -1241,7 +1244,7 @@ static inline struct hci_conn *hci_conn_hash_lookup_cis(struct hci_dev *hdev, > rcu_read_lock(); > > list_for_each_entry_rcu(c, &h->list, list) { > - if (c->type != ISO_LINK || !bacmp(&c->dst, BDADDR_ANY)) > + if (c->type != ISO_LINK_UCAST) > continue; > > /* Match CIG ID if set */ > @@ -1273,7 +1276,7 @@ static inline struct hci_conn *hci_conn_hash_lookup_cig(struct hci_dev *hdev, > rcu_read_lock(); > > list_for_each_entry_rcu(c, &h->list, list) { > - if (c->type != ISO_LINK || !bacmp(&c->dst, BDADDR_ANY)) > + if (c->type != ISO_LINK_UCAST) > continue; > > if (handle == c->iso_qos.ucast.cig) { > @@ -1296,17 +1299,7 @@ static inline struct hci_conn *hci_conn_hash_lookup_big(struct hci_dev *hdev, > rcu_read_lock(); > > list_for_each_entry_rcu(c, &h->list, list) { > - if (c->type != ISO_LINK) > - continue; > - > - /* An ISO_LINK hcon with BDADDR_ANY as destination > - * address is a Broadcast connection. A Broadcast > - * slave connection is associated with a PA train, > - * so the sync_handle can be used to differentiate > - * from unicast. > - */ > - if (bacmp(&c->dst, BDADDR_ANY) && > - c->sync_handle == HCI_SYNC_HANDLE_INVALID) > + if (c->type != ISO_LINK_BCAST) > continue; > > if (handle == c->iso_qos.bcast.big) { > @@ -1330,7 +1323,7 @@ hci_conn_hash_lookup_big_sync_pend(struct hci_dev *hdev, > rcu_read_lock(); > > list_for_each_entry_rcu(c, &h->list, list) { > - if (c->type != ISO_LINK) > + if (c->type != ISO_LINK_BCAST) > continue; > > if (handle == c->iso_qos.bcast.big && num_bis == c->num_bis) { > @@ -1353,8 +1346,8 @@ hci_conn_hash_lookup_big_state(struct hci_dev *hdev, __u8 handle, __u16 state) > rcu_read_lock(); > > list_for_each_entry_rcu(c, &h->list, list) { > - if (bacmp(&c->dst, BDADDR_ANY) || c->type != ISO_LINK || > - c->state != state) > + if (c->type != ISO_LINK_BCAST || bacmp(&c->dst, BDADDR_ANY) || > + c->state != state) > continue; > > if (handle == c->iso_qos.bcast.big) { > @@ -1377,8 +1370,8 @@ hci_conn_hash_lookup_pa_sync_big_handle(struct hci_dev *hdev, __u8 big) > rcu_read_lock(); > > list_for_each_entry_rcu(c, &h->list, list) { > - if (c->type != ISO_LINK || > - !test_bit(HCI_CONN_PA_SYNC, &c->flags)) > + if (c->type != ISO_LINK_BCAST || > + !test_bit(HCI_CONN_PA_SYNC, &c->flags)) > continue; > > if (c->iso_qos.bcast.big == big) { > @@ -1400,7 +1393,7 @@ hci_conn_hash_lookup_pa_sync_handle(struct hci_dev *hdev, __u16 sync_handle) > rcu_read_lock(); > > list_for_each_entry_rcu(c, &h->list, list) { > - if (c->type != ISO_LINK) > + if (c->type != ISO_LINK_BCAST) > continue; > > /* Ignore the listen hcon, we are looking > @@ -2014,7 +2007,8 @@ static inline int hci_proto_connect_ind(struct hci_dev *hdev, bdaddr_t *bdaddr, > case ESCO_LINK: > return sco_connect_ind(hdev, bdaddr, flags); > > - case ISO_LINK: > + case ISO_LINK_UCAST: > + case ISO_LINK_BCAST: > return iso_connect_ind(hdev, bdaddr, flags); > > default: > diff --git a/net/bluetooth/hci_conn.c b/net/bluetooth/hci_conn.c > index d8f6aaf14703..ba56d5212cec 100644 > --- a/net/bluetooth/hci_conn.c > +++ b/net/bluetooth/hci_conn.c > @@ -785,7 +785,7 @@ static int hci_le_big_terminate(struct hci_dev *hdev, u8 big, struct hci_conn *c > d->sync_handle = conn->sync_handle; > > if (test_and_clear_bit(HCI_CONN_PA_SYNC, &conn->flags)) { > - hci_conn_hash_list_flag(hdev, find_bis, ISO_LINK, > + hci_conn_hash_list_flag(hdev, find_bis, ISO_LINK_BCAST, > HCI_CONN_PA_SYNC, d); > > if (!d->count) > @@ -795,7 +795,7 @@ static int hci_le_big_terminate(struct hci_dev *hdev, u8 big, struct hci_conn *c > } > > if (test_and_clear_bit(HCI_CONN_BIG_SYNC, &conn->flags)) { > - hci_conn_hash_list_flag(hdev, find_bis, ISO_LINK, > + hci_conn_hash_list_flag(hdev, find_bis, ISO_LINK_BCAST, > HCI_CONN_BIG_SYNC, d); > > if (!d->count) > @@ -885,9 +885,11 @@ static void cis_cleanup(struct hci_conn *conn) > /* Check if ISO connection is a CIS and remove CIG if there are > * no other connections using it. > */ > - hci_conn_hash_list_state(hdev, find_cis, ISO_LINK, BT_BOUND, &d); > - hci_conn_hash_list_state(hdev, find_cis, ISO_LINK, BT_CONNECT, &d); > - hci_conn_hash_list_state(hdev, find_cis, ISO_LINK, BT_CONNECTED, &d); > + hci_conn_hash_list_state(hdev, find_cis, ISO_LINK_UCAST, BT_BOUND, &d); > + hci_conn_hash_list_state(hdev, find_cis, ISO_LINK_UCAST, BT_CONNECT, > + &d); > + hci_conn_hash_list_state(hdev, find_cis, ISO_LINK_UCAST, BT_CONNECTED, > + &d); > if (d.count) > return; > > @@ -910,7 +912,8 @@ static struct hci_conn *__hci_conn_add(struct hci_dev *hdev, int type, bdaddr_t > if (!hdev->acl_mtu) > return ERR_PTR(-ECONNREFUSED); > break; > - case ISO_LINK: > + case ISO_LINK_UCAST: > + case ISO_LINK_BCAST: > if (hdev->iso_mtu) > /* Dedicated ISO Buffer exists */ > break; > @@ -974,7 +977,8 @@ static struct hci_conn *__hci_conn_add(struct hci_dev *hdev, int type, bdaddr_t > hci_copy_identity_address(hdev, &conn->src, &conn->src_type); > conn->mtu = hdev->le_mtu ? hdev->le_mtu : hdev->acl_mtu; > break; > - case ISO_LINK: > + case ISO_LINK_UCAST: > + case ISO_LINK_BCAST: > /* conn->src should reflect the local identity address */ > hci_copy_identity_address(hdev, &conn->src, &conn->src_type); > > @@ -1071,7 +1075,8 @@ static void hci_conn_cleanup_child(struct hci_conn *conn, u8 reason) > if (HCI_CONN_HANDLE_UNSET(conn->handle)) > hci_conn_failed(conn, reason); > break; > - case ISO_LINK: > + case ISO_LINK_UCAST: > + case ISO_LINK_BCAST: > if ((conn->state != BT_CONNECTED && > !test_bit(HCI_CONN_CREATE_CIS, &conn->flags)) || > test_bit(HCI_CONN_BIG_CREATED, &conn->flags)) > @@ -1146,7 +1151,8 @@ void hci_conn_del(struct hci_conn *conn) > hdev->acl_cnt += conn->sent; > } else { > /* Unacked ISO frames */ > - if (conn->type == ISO_LINK) { > + if (conn->type == ISO_LINK_UCAST || > + conn->type == ISO_LINK_BCAST) { > if (hdev->iso_pkts) > hdev->iso_cnt += conn->sent; > else if (hdev->le_pkts) > @@ -1532,7 +1538,7 @@ static struct hci_conn *hci_add_bis(struct hci_dev *hdev, bdaddr_t *dst, > memcmp(conn->le_per_adv_data, base, base_len))) > return ERR_PTR(-EADDRINUSE); > > - conn = hci_conn_add_unset(hdev, ISO_LINK, dst, HCI_ROLE_MASTER); > + conn = hci_conn_add_unset(hdev, ISO_LINK_BCAST, dst, HCI_ROLE_MASTER); > if (IS_ERR(conn)) > return conn; > > @@ -1740,7 +1746,7 @@ static int hci_le_create_big(struct hci_conn *conn, struct bt_iso_qos *qos) > data.count = 0; > > /* Create a BIS for each bound connection */ > - hci_conn_hash_list_state(hdev, bis_list, ISO_LINK, > + hci_conn_hash_list_state(hdev, bis_list, ISO_LINK_BCAST, > BT_BOUND, &data); > > cp.handle = qos->bcast.big; > @@ -1829,12 +1835,12 @@ static bool hci_le_set_cig_params(struct hci_conn *conn, struct bt_iso_qos *qos) > for (data.cig = 0x00; data.cig < 0xf0; data.cig++) { > data.count = 0; > > - hci_conn_hash_list_state(hdev, find_cis, ISO_LINK, > + hci_conn_hash_list_state(hdev, find_cis, ISO_LINK_UCAST, > BT_CONNECT, &data); > if (data.count) > continue; > > - hci_conn_hash_list_state(hdev, find_cis, ISO_LINK, > + hci_conn_hash_list_state(hdev, find_cis, ISO_LINK_UCAST, > BT_CONNECTED, &data); > if (!data.count) > break; > @@ -1884,7 +1890,8 @@ struct hci_conn *hci_bind_cis(struct hci_dev *hdev, bdaddr_t *dst, > cis = hci_conn_hash_lookup_cis(hdev, dst, dst_type, qos->ucast.cig, > qos->ucast.cis); > if (!cis) { > - cis = hci_conn_add_unset(hdev, ISO_LINK, dst, HCI_ROLE_MASTER); > + cis = hci_conn_add_unset(hdev, ISO_LINK_UCAST, dst, > + HCI_ROLE_MASTER); > if (IS_ERR(cis)) > return cis; > cis->cleanup = cis_cleanup; > @@ -1976,7 +1983,7 @@ bool hci_iso_setup_path(struct hci_conn *conn) > > int hci_conn_check_create_cis(struct hci_conn *conn) > { > - if (conn->type != ISO_LINK || !bacmp(&conn->dst, BDADDR_ANY)) > + if (conn->type != ISO_LINK_UCAST) > return -EINVAL; > > if (!conn->parent || conn->parent->state != BT_CONNECTED || > @@ -2072,7 +2079,7 @@ struct hci_conn *hci_pa_create_sync(struct hci_dev *hdev, bdaddr_t *dst, > > bt_dev_dbg(hdev, "dst %pMR type %d sid %d", dst, dst_type, sid); > > - conn = hci_conn_add_unset(hdev, ISO_LINK, dst, HCI_ROLE_SLAVE); > + conn = hci_conn_add_unset(hdev, ISO_LINK_BCAST, dst, HCI_ROLE_SLAVE); > if (IS_ERR(conn)) > return conn; > > @@ -2221,7 +2228,7 @@ struct hci_conn *hci_connect_bis(struct hci_dev *hdev, bdaddr_t *dst, > * the start periodic advertising and create BIG commands have > * been queued > */ > - hci_conn_hash_list_state(hdev, bis_mark_per_adv, ISO_LINK, > + hci_conn_hash_list_state(hdev, bis_mark_per_adv, ISO_LINK_BCAST, > BT_BOUND, &data); > > /* Queue start periodic advertising and create BIG */ > @@ -2953,7 +2960,8 @@ void hci_conn_tx_queue(struct hci_conn *conn, struct sk_buff *skb) > * TODO: SCO support without flowctl (needs to be done in drivers) > */ > switch (conn->type) { > - case ISO_LINK: > + case ISO_LINK_UCAST: > + case ISO_LINK_BCAST: > case ACL_LINK: > case LE_LINK: > break; > diff --git a/net/bluetooth/hci_core.c b/net/bluetooth/hci_core.c > index a58fd3bf8851..0c4b07115563 100644 > --- a/net/bluetooth/hci_core.c > +++ b/net/bluetooth/hci_core.c > @@ -2898,12 +2898,13 @@ int hci_recv_frame(struct hci_dev *hdev, struct sk_buff *skb) > break; > case HCI_ACLDATA_PKT: > /* Detect if ISO packet has been sent as ACL */ > - if (hci_conn_num(hdev, ISO_LINK)) { > + if (hci_conn_num(hdev, ISO_LINK_UCAST) || > + hci_conn_num(hdev, ISO_LINK_BCAST)) { > __u16 handle = __le16_to_cpu(hci_acl_hdr(skb)->handle); > __u8 type; > > type = hci_conn_lookup_type(hdev, hci_handle(handle)); > - if (type == ISO_LINK) > + if (type == ISO_LINK_UCAST || type == ISO_LINK_BCAST) > hci_skb_pkt_type(skb) = HCI_ISODATA_PKT; > } > break; > @@ -3356,7 +3357,8 @@ static inline void hci_quote_sent(struct hci_conn *conn, int num, int *quote) > case LE_LINK: > cnt = hdev->le_mtu ? hdev->le_cnt : hdev->acl_cnt; > break; > - case ISO_LINK: > + case ISO_LINK_UCAST: > + case ISO_LINK_BCAST: > cnt = hdev->iso_mtu ? hdev->iso_cnt : > hdev->le_mtu ? hdev->le_cnt : hdev->acl_cnt; > break; > @@ -3370,7 +3372,7 @@ static inline void hci_quote_sent(struct hci_conn *conn, int num, int *quote) > } > > static struct hci_conn *hci_low_sent(struct hci_dev *hdev, __u8 type, > - int *quote) > + __u8 type2, int *quote) > { > struct hci_conn_hash *h = &hdev->conn_hash; > struct hci_conn *conn = NULL, *c; > @@ -3382,7 +3384,8 @@ static struct hci_conn *hci_low_sent(struct hci_dev *hdev, __u8 type, > rcu_read_lock(); > > list_for_each_entry_rcu(c, &h->list, list) { > - if (c->type != type || skb_queue_empty(&c->data_q)) > + if ((c->type != type && c->type != type2) || > + skb_queue_empty(&c->data_q)) > continue; > > if (c->state != BT_CONNECTED && c->state != BT_CONFIG) > @@ -3590,7 +3593,7 @@ static void hci_sched_sco(struct hci_dev *hdev, __u8 type) > else > cnt = &hdev->sco_cnt; > > - while (*cnt && (conn = hci_low_sent(hdev, type, "e))) { > + while (*cnt && (conn = hci_low_sent(hdev, type, type, "e))) { > while (quote-- && (skb = skb_dequeue(&conn->data_q))) { > BT_DBG("skb %p len %d", skb, skb->len); > hci_send_conn_frame(hdev, conn, skb); > @@ -3718,12 +3721,14 @@ static void hci_sched_iso(struct hci_dev *hdev) > > BT_DBG("%s", hdev->name); > > - if (!hci_conn_num(hdev, ISO_LINK)) > + if (!hci_conn_num(hdev, ISO_LINK_UCAST) && > + !hci_conn_num(hdev, ISO_LINK_BCAST)) > return; > > cnt = hdev->iso_pkts ? &hdev->iso_cnt : > hdev->le_pkts ? &hdev->le_cnt : &hdev->acl_cnt; > - while (*cnt && (conn = hci_low_sent(hdev, ISO_LINK, "e))) { > + while (*cnt && (conn = hci_low_sent(hdev, ISO_LINK_UCAST, > + ISO_LINK_BCAST, "e))) { > while (quote-- && (skb = skb_dequeue(&conn->data_q))) { > BT_DBG("skb %p len %d", skb, skb->len); > hci_send_conn_frame(hdev, conn, skb); > diff --git a/net/bluetooth/hci_event.c b/net/bluetooth/hci_event.c > index 105d1446c9dc..6ecf36afaae0 100644 > --- a/net/bluetooth/hci_event.c > +++ b/net/bluetooth/hci_event.c > @@ -3793,7 +3793,7 @@ static void hci_unbound_cis_failed(struct hci_dev *hdev, u8 cig, u8 status) > lockdep_assert_held(&hdev->lock); > > list_for_each_entry_safe(conn, tmp, &hdev->conn_hash.list, list) { > - if (conn->type != ISO_LINK || !bacmp(&conn->dst, BDADDR_ANY) || > + if (conn->type != ISO_LINK_UCAST || > conn->state == BT_OPEN || conn->iso_qos.ucast.cig != cig) > continue; > > @@ -4456,7 +4456,8 @@ static void hci_num_comp_pkts_evt(struct hci_dev *hdev, void *data, > > break; > > - case ISO_LINK: > + case ISO_LINK_UCAST: > + case ISO_LINK_BCAST: > if (hdev->iso_pkts) { > hdev->iso_cnt += count; > if (hdev->iso_cnt > hdev->iso_pkts) > @@ -6402,7 +6403,8 @@ static void hci_le_pa_sync_estabilished_evt(struct hci_dev *hdev, void *data, > conn->sync_handle = le16_to_cpu(ev->handle); > conn->sid = HCI_SID_INVALID; > > - mask |= hci_proto_connect_ind(hdev, &ev->bdaddr, ISO_LINK, &flags); > + mask |= hci_proto_connect_ind(hdev, &ev->bdaddr, ISO_LINK_BCAST, > + &flags); > if (!(mask & HCI_LM_ACCEPT)) { > hci_le_pa_term_sync(hdev, ev->handle); > goto unlock; > @@ -6412,7 +6414,7 @@ static void hci_le_pa_sync_estabilished_evt(struct hci_dev *hdev, void *data, > goto unlock; > > /* Add connection to indicate PA sync event */ > - pa_sync = hci_conn_add_unset(hdev, ISO_LINK, BDADDR_ANY, > + pa_sync = hci_conn_add_unset(hdev, ISO_LINK_BCAST, BDADDR_ANY, > HCI_ROLE_SLAVE); > > if (IS_ERR(pa_sync)) > @@ -6443,7 +6445,7 @@ static void hci_le_per_adv_report_evt(struct hci_dev *hdev, void *data, > > hci_dev_lock(hdev); > > - mask |= hci_proto_connect_ind(hdev, BDADDR_ANY, ISO_LINK, &flags); > + mask |= hci_proto_connect_ind(hdev, BDADDR_ANY, ISO_LINK_BCAST, &flags); > if (!(mask & HCI_LM_ACCEPT)) > goto unlock; > > @@ -6727,7 +6729,7 @@ static void hci_le_cis_estabilished_evt(struct hci_dev *hdev, void *data, > goto unlock; > } > > - if (conn->type != ISO_LINK) { > + if (conn->type != ISO_LINK_UCAST) { > bt_dev_err(hdev, > "Invalid connection link type handle 0x%4.4x", > handle); > @@ -6845,7 +6847,7 @@ static void hci_le_cis_req_evt(struct hci_dev *hdev, void *data, > if (!acl) > goto unlock; > > - mask = hci_proto_connect_ind(hdev, &acl->dst, ISO_LINK, &flags); > + mask = hci_proto_connect_ind(hdev, &acl->dst, ISO_LINK_UCAST, &flags); > if (!(mask & HCI_LM_ACCEPT)) { > hci_le_reject_cis(hdev, ev->cis_handle); > goto unlock; > @@ -6853,8 +6855,8 @@ static void hci_le_cis_req_evt(struct hci_dev *hdev, void *data, > > cis = hci_conn_hash_lookup_handle(hdev, cis_handle); > if (!cis) { > - cis = hci_conn_add(hdev, ISO_LINK, &acl->dst, HCI_ROLE_SLAVE, > - cis_handle); > + cis = hci_conn_add(hdev, ISO_LINK_UCAST, &acl->dst, > + HCI_ROLE_SLAVE, cis_handle); > if (IS_ERR(cis)) { > hci_le_reject_cis(hdev, ev->cis_handle); > goto unlock; > @@ -6969,7 +6971,7 @@ static void hci_le_big_sync_established_evt(struct hci_dev *hdev, void *data, > bt_dev_dbg(hdev, "ignore too large handle %u", handle); > continue; > } > - bis = hci_conn_add(hdev, ISO_LINK, BDADDR_ANY, > + bis = hci_conn_add(hdev, ISO_LINK_BCAST, BDADDR_ANY, > HCI_ROLE_SLAVE, handle); > if (IS_ERR(bis)) > continue; > @@ -7025,7 +7027,7 @@ static void hci_le_big_info_adv_report_evt(struct hci_dev *hdev, void *data, > > hci_dev_lock(hdev); > > - mask |= hci_proto_connect_ind(hdev, BDADDR_ANY, ISO_LINK, &flags); > + mask |= hci_proto_connect_ind(hdev, BDADDR_ANY, ISO_LINK_BCAST, &flags); > if (!(mask & HCI_LM_ACCEPT)) > goto unlock; > > diff --git a/net/bluetooth/hci_sync.c b/net/bluetooth/hci_sync.c > index d00ff18f3be0..5f37335140a9 100644 > --- a/net/bluetooth/hci_sync.c > +++ b/net/bluetooth/hci_sync.c > @@ -2860,7 +2860,7 @@ static int hci_le_set_ext_scan_param_sync(struct hci_dev *hdev, u8 type, > if (sent) { > struct hci_conn *conn; > > - conn = hci_conn_hash_lookup_ba(hdev, ISO_LINK, > + conn = hci_conn_hash_lookup_ba(hdev, ISO_LINK_BCAST, > &sent->bdaddr); > if (conn) { > struct bt_iso_qos *qos = &conn->iso_qos; > @@ -5477,7 +5477,7 @@ static int hci_connect_cancel_sync(struct hci_dev *hdev, struct hci_conn *conn, > if (conn->type == LE_LINK) > return hci_le_connect_cancel_sync(hdev, conn, reason); > > - if (conn->type == ISO_LINK) { > + if (conn->type == ISO_LINK_UCAST) { > /* BLUETOOTH CORE SPECIFICATION Version 5.3 | Vol 4, Part E > * page 1857: > * > @@ -5490,9 +5490,10 @@ static int hci_connect_cancel_sync(struct hci_dev *hdev, struct hci_conn *conn, > return hci_disconnect_sync(hdev, conn, reason); > > /* CIS with no Create CIS sent have nothing to cancel */ > - if (bacmp(&conn->dst, BDADDR_ANY)) > - return HCI_ERROR_LOCAL_HOST_TERM; > + return HCI_ERROR_LOCAL_HOST_TERM; > + } > > + if (conn->type == ISO_LINK_BCAST) { > /* There is no way to cancel a BIS without terminating the BIG > * which is done later on connection cleanup. > */ > @@ -5554,9 +5555,12 @@ static int hci_reject_conn_sync(struct hci_dev *hdev, struct hci_conn *conn, > { > struct hci_cp_reject_conn_req cp; > > - if (conn->type == ISO_LINK) > + if (conn->type == ISO_LINK_UCAST) > return hci_le_reject_cis_sync(hdev, conn, reason); > > + if (conn->type == ISO_LINK_BCAST) > + return -EINVAL; > + > if (conn->type == SCO_LINK || conn->type == ESCO_LINK) > return hci_reject_sco_sync(hdev, conn, reason); > > @@ -6917,7 +6921,7 @@ static void create_pa_complete(struct hci_dev *hdev, void *data, int err) > goto unlock; > > /* Add connection to indicate PA sync error */ > - pa_sync = hci_conn_add_unset(hdev, ISO_LINK, BDADDR_ANY, > + pa_sync = hci_conn_add_unset(hdev, ISO_LINK_BCAST, BDADDR_ANY, > HCI_ROLE_SLAVE); > > if (IS_ERR(pa_sync)) > diff --git a/net/bluetooth/iso.c b/net/bluetooth/iso.c > index 2f348f48e99d..608c8bf72128 100644 > --- a/net/bluetooth/iso.c > +++ b/net/bluetooth/iso.c > @@ -2219,7 +2219,7 @@ int iso_connect_ind(struct hci_dev *hdev, bdaddr_t *bdaddr, __u8 *flags) > > static void iso_connect_cfm(struct hci_conn *hcon, __u8 status) > { > - if (hcon->type != ISO_LINK) { > + if (hcon->type != ISO_LINK_UCAST && hcon->type != ISO_LINK_BCAST) { > if (hcon->type != LE_LINK) > return; > > @@ -2260,7 +2260,7 @@ static void iso_connect_cfm(struct hci_conn *hcon, __u8 status) > > static void iso_disconn_cfm(struct hci_conn *hcon, __u8 reason) > { > - if (hcon->type != ISO_LINK) > + if (hcon->type != ISO_LINK_UCAST && hcon->type != ISO_LINK_BCAST) > return; > > BT_DBG("hcon %p reason %d", hcon, reason); > diff --git a/net/bluetooth/mgmt.c b/net/bluetooth/mgmt.c > index 46b22708dfbd..26700394349c 100644 > --- a/net/bluetooth/mgmt.c > +++ b/net/bluetooth/mgmt.c > @@ -3221,7 +3221,8 @@ static int disconnect(struct sock *sk, struct hci_dev *hdev, void *data, > static u8 link_to_bdaddr(u8 link_type, u8 addr_type) > { > switch (link_type) { > - case ISO_LINK: > + case ISO_LINK_UCAST: > + case ISO_LINK_BCAST: > case LE_LINK: > switch (addr_type) { > case ADDR_LE_DEV_PUBLIC: > -- > 2.49.0 > >
diff --git a/include/net/bluetooth/hci.h b/include/net/bluetooth/hci.h index 2502febf4da7..4d19fde81770 100644 --- a/include/net/bluetooth/hci.h +++ b/include/net/bluetooth/hci.h @@ -558,7 +558,8 @@ enum { #define ESCO_LINK 0x02 /* Low Energy links do not have defined link type. Use invented one */ #define LE_LINK 0x80 -#define ISO_LINK 0x82 +#define ISO_LINK_UCAST 0x82 +#define ISO_LINK_BCAST 0x83 #define INVALID_LINK 0xff /* LMP features */ diff --git a/include/net/bluetooth/hci_core.h b/include/net/bluetooth/hci_core.h index 965ca1ca841c..7f89a19ca1d9 100644 --- a/include/net/bluetooth/hci_core.h +++ b/include/net/bluetooth/hci_core.h @@ -999,7 +999,8 @@ static inline void hci_conn_hash_add(struct hci_dev *hdev, struct hci_conn *c) case ESCO_LINK: h->sco_num++; break; - case ISO_LINK: + case ISO_LINK_UCAST: + case ISO_LINK_BCAST: h->iso_num++; break; } @@ -1025,7 +1026,8 @@ static inline void hci_conn_hash_del(struct hci_dev *hdev, struct hci_conn *c) case ESCO_LINK: h->sco_num--; break; - case ISO_LINK: + case ISO_LINK_UCAST: + case ISO_LINK_BCAST: h->iso_num--; break; } @@ -1042,7 +1044,8 @@ static inline unsigned int hci_conn_num(struct hci_dev *hdev, __u8 type) case SCO_LINK: case ESCO_LINK: return h->sco_num; - case ISO_LINK: + case ISO_LINK_UCAST: + case ISO_LINK_BCAST: return h->iso_num; default: return 0; @@ -1103,7 +1106,7 @@ static inline struct hci_conn *hci_conn_hash_lookup_bis(struct hci_dev *hdev, rcu_read_lock(); list_for_each_entry_rcu(c, &h->list, list) { - if (bacmp(&c->dst, ba) || c->type != ISO_LINK) + if (bacmp(&c->dst, ba) || c->type != ISO_LINK_BCAST) continue; if (c->iso_qos.bcast.bis == bis) { @@ -1125,7 +1128,7 @@ hci_conn_hash_lookup_create_pa_sync(struct hci_dev *hdev) rcu_read_lock(); list_for_each_entry_rcu(c, &h->list, list) { - if (c->type != ISO_LINK) + if (c->type != ISO_LINK_BCAST) continue; if (!test_bit(HCI_CONN_CREATE_PA_SYNC, &c->flags)) @@ -1151,8 +1154,8 @@ hci_conn_hash_lookup_per_adv_bis(struct hci_dev *hdev, rcu_read_lock(); list_for_each_entry_rcu(c, &h->list, list) { - if (bacmp(&c->dst, ba) || c->type != ISO_LINK || - !test_bit(HCI_CONN_PER_ADV, &c->flags)) + if (bacmp(&c->dst, ba) || c->type != ISO_LINK_BCAST || + !test_bit(HCI_CONN_PER_ADV, &c->flags)) continue; if (c->iso_qos.bcast.big == big && @@ -1241,7 +1244,7 @@ static inline struct hci_conn *hci_conn_hash_lookup_cis(struct hci_dev *hdev, rcu_read_lock(); list_for_each_entry_rcu(c, &h->list, list) { - if (c->type != ISO_LINK || !bacmp(&c->dst, BDADDR_ANY)) + if (c->type != ISO_LINK_UCAST) continue; /* Match CIG ID if set */ @@ -1273,7 +1276,7 @@ static inline struct hci_conn *hci_conn_hash_lookup_cig(struct hci_dev *hdev, rcu_read_lock(); list_for_each_entry_rcu(c, &h->list, list) { - if (c->type != ISO_LINK || !bacmp(&c->dst, BDADDR_ANY)) + if (c->type != ISO_LINK_UCAST) continue; if (handle == c->iso_qos.ucast.cig) { @@ -1296,17 +1299,7 @@ static inline struct hci_conn *hci_conn_hash_lookup_big(struct hci_dev *hdev, rcu_read_lock(); list_for_each_entry_rcu(c, &h->list, list) { - if (c->type != ISO_LINK) - continue; - - /* An ISO_LINK hcon with BDADDR_ANY as destination - * address is a Broadcast connection. A Broadcast - * slave connection is associated with a PA train, - * so the sync_handle can be used to differentiate - * from unicast. - */ - if (bacmp(&c->dst, BDADDR_ANY) && - c->sync_handle == HCI_SYNC_HANDLE_INVALID) + if (c->type != ISO_LINK_BCAST) continue; if (handle == c->iso_qos.bcast.big) { @@ -1330,7 +1323,7 @@ hci_conn_hash_lookup_big_sync_pend(struct hci_dev *hdev, rcu_read_lock(); list_for_each_entry_rcu(c, &h->list, list) { - if (c->type != ISO_LINK) + if (c->type != ISO_LINK_BCAST) continue; if (handle == c->iso_qos.bcast.big && num_bis == c->num_bis) { @@ -1353,8 +1346,8 @@ hci_conn_hash_lookup_big_state(struct hci_dev *hdev, __u8 handle, __u16 state) rcu_read_lock(); list_for_each_entry_rcu(c, &h->list, list) { - if (bacmp(&c->dst, BDADDR_ANY) || c->type != ISO_LINK || - c->state != state) + if (c->type != ISO_LINK_BCAST || bacmp(&c->dst, BDADDR_ANY) || + c->state != state) continue; if (handle == c->iso_qos.bcast.big) { @@ -1377,8 +1370,8 @@ hci_conn_hash_lookup_pa_sync_big_handle(struct hci_dev *hdev, __u8 big) rcu_read_lock(); list_for_each_entry_rcu(c, &h->list, list) { - if (c->type != ISO_LINK || - !test_bit(HCI_CONN_PA_SYNC, &c->flags)) + if (c->type != ISO_LINK_BCAST || + !test_bit(HCI_CONN_PA_SYNC, &c->flags)) continue; if (c->iso_qos.bcast.big == big) { @@ -1400,7 +1393,7 @@ hci_conn_hash_lookup_pa_sync_handle(struct hci_dev *hdev, __u16 sync_handle) rcu_read_lock(); list_for_each_entry_rcu(c, &h->list, list) { - if (c->type != ISO_LINK) + if (c->type != ISO_LINK_BCAST) continue; /* Ignore the listen hcon, we are looking @@ -2014,7 +2007,8 @@ static inline int hci_proto_connect_ind(struct hci_dev *hdev, bdaddr_t *bdaddr, case ESCO_LINK: return sco_connect_ind(hdev, bdaddr, flags); - case ISO_LINK: + case ISO_LINK_UCAST: + case ISO_LINK_BCAST: return iso_connect_ind(hdev, bdaddr, flags); default: diff --git a/net/bluetooth/hci_conn.c b/net/bluetooth/hci_conn.c index d8f6aaf14703..ba56d5212cec 100644 --- a/net/bluetooth/hci_conn.c +++ b/net/bluetooth/hci_conn.c @@ -785,7 +785,7 @@ static int hci_le_big_terminate(struct hci_dev *hdev, u8 big, struct hci_conn *c d->sync_handle = conn->sync_handle; if (test_and_clear_bit(HCI_CONN_PA_SYNC, &conn->flags)) { - hci_conn_hash_list_flag(hdev, find_bis, ISO_LINK, + hci_conn_hash_list_flag(hdev, find_bis, ISO_LINK_BCAST, HCI_CONN_PA_SYNC, d); if (!d->count) @@ -795,7 +795,7 @@ static int hci_le_big_terminate(struct hci_dev *hdev, u8 big, struct hci_conn *c } if (test_and_clear_bit(HCI_CONN_BIG_SYNC, &conn->flags)) { - hci_conn_hash_list_flag(hdev, find_bis, ISO_LINK, + hci_conn_hash_list_flag(hdev, find_bis, ISO_LINK_BCAST, HCI_CONN_BIG_SYNC, d); if (!d->count) @@ -885,9 +885,11 @@ static void cis_cleanup(struct hci_conn *conn) /* Check if ISO connection is a CIS and remove CIG if there are * no other connections using it. */ - hci_conn_hash_list_state(hdev, find_cis, ISO_LINK, BT_BOUND, &d); - hci_conn_hash_list_state(hdev, find_cis, ISO_LINK, BT_CONNECT, &d); - hci_conn_hash_list_state(hdev, find_cis, ISO_LINK, BT_CONNECTED, &d); + hci_conn_hash_list_state(hdev, find_cis, ISO_LINK_UCAST, BT_BOUND, &d); + hci_conn_hash_list_state(hdev, find_cis, ISO_LINK_UCAST, BT_CONNECT, + &d); + hci_conn_hash_list_state(hdev, find_cis, ISO_LINK_UCAST, BT_CONNECTED, + &d); if (d.count) return; @@ -910,7 +912,8 @@ static struct hci_conn *__hci_conn_add(struct hci_dev *hdev, int type, bdaddr_t if (!hdev->acl_mtu) return ERR_PTR(-ECONNREFUSED); break; - case ISO_LINK: + case ISO_LINK_UCAST: + case ISO_LINK_BCAST: if (hdev->iso_mtu) /* Dedicated ISO Buffer exists */ break; @@ -974,7 +977,8 @@ static struct hci_conn *__hci_conn_add(struct hci_dev *hdev, int type, bdaddr_t hci_copy_identity_address(hdev, &conn->src, &conn->src_type); conn->mtu = hdev->le_mtu ? hdev->le_mtu : hdev->acl_mtu; break; - case ISO_LINK: + case ISO_LINK_UCAST: + case ISO_LINK_BCAST: /* conn->src should reflect the local identity address */ hci_copy_identity_address(hdev, &conn->src, &conn->src_type); @@ -1071,7 +1075,8 @@ static void hci_conn_cleanup_child(struct hci_conn *conn, u8 reason) if (HCI_CONN_HANDLE_UNSET(conn->handle)) hci_conn_failed(conn, reason); break; - case ISO_LINK: + case ISO_LINK_UCAST: + case ISO_LINK_BCAST: if ((conn->state != BT_CONNECTED && !test_bit(HCI_CONN_CREATE_CIS, &conn->flags)) || test_bit(HCI_CONN_BIG_CREATED, &conn->flags)) @@ -1146,7 +1151,8 @@ void hci_conn_del(struct hci_conn *conn) hdev->acl_cnt += conn->sent; } else { /* Unacked ISO frames */ - if (conn->type == ISO_LINK) { + if (conn->type == ISO_LINK_UCAST || + conn->type == ISO_LINK_BCAST) { if (hdev->iso_pkts) hdev->iso_cnt += conn->sent; else if (hdev->le_pkts) @@ -1532,7 +1538,7 @@ static struct hci_conn *hci_add_bis(struct hci_dev *hdev, bdaddr_t *dst, memcmp(conn->le_per_adv_data, base, base_len))) return ERR_PTR(-EADDRINUSE); - conn = hci_conn_add_unset(hdev, ISO_LINK, dst, HCI_ROLE_MASTER); + conn = hci_conn_add_unset(hdev, ISO_LINK_BCAST, dst, HCI_ROLE_MASTER); if (IS_ERR(conn)) return conn; @@ -1740,7 +1746,7 @@ static int hci_le_create_big(struct hci_conn *conn, struct bt_iso_qos *qos) data.count = 0; /* Create a BIS for each bound connection */ - hci_conn_hash_list_state(hdev, bis_list, ISO_LINK, + hci_conn_hash_list_state(hdev, bis_list, ISO_LINK_BCAST, BT_BOUND, &data); cp.handle = qos->bcast.big; @@ -1829,12 +1835,12 @@ static bool hci_le_set_cig_params(struct hci_conn *conn, struct bt_iso_qos *qos) for (data.cig = 0x00; data.cig < 0xf0; data.cig++) { data.count = 0; - hci_conn_hash_list_state(hdev, find_cis, ISO_LINK, + hci_conn_hash_list_state(hdev, find_cis, ISO_LINK_UCAST, BT_CONNECT, &data); if (data.count) continue; - hci_conn_hash_list_state(hdev, find_cis, ISO_LINK, + hci_conn_hash_list_state(hdev, find_cis, ISO_LINK_UCAST, BT_CONNECTED, &data); if (!data.count) break; @@ -1884,7 +1890,8 @@ struct hci_conn *hci_bind_cis(struct hci_dev *hdev, bdaddr_t *dst, cis = hci_conn_hash_lookup_cis(hdev, dst, dst_type, qos->ucast.cig, qos->ucast.cis); if (!cis) { - cis = hci_conn_add_unset(hdev, ISO_LINK, dst, HCI_ROLE_MASTER); + cis = hci_conn_add_unset(hdev, ISO_LINK_UCAST, dst, + HCI_ROLE_MASTER); if (IS_ERR(cis)) return cis; cis->cleanup = cis_cleanup; @@ -1976,7 +1983,7 @@ bool hci_iso_setup_path(struct hci_conn *conn) int hci_conn_check_create_cis(struct hci_conn *conn) { - if (conn->type != ISO_LINK || !bacmp(&conn->dst, BDADDR_ANY)) + if (conn->type != ISO_LINK_UCAST) return -EINVAL; if (!conn->parent || conn->parent->state != BT_CONNECTED || @@ -2072,7 +2079,7 @@ struct hci_conn *hci_pa_create_sync(struct hci_dev *hdev, bdaddr_t *dst, bt_dev_dbg(hdev, "dst %pMR type %d sid %d", dst, dst_type, sid); - conn = hci_conn_add_unset(hdev, ISO_LINK, dst, HCI_ROLE_SLAVE); + conn = hci_conn_add_unset(hdev, ISO_LINK_BCAST, dst, HCI_ROLE_SLAVE); if (IS_ERR(conn)) return conn; @@ -2221,7 +2228,7 @@ struct hci_conn *hci_connect_bis(struct hci_dev *hdev, bdaddr_t *dst, * the start periodic advertising and create BIG commands have * been queued */ - hci_conn_hash_list_state(hdev, bis_mark_per_adv, ISO_LINK, + hci_conn_hash_list_state(hdev, bis_mark_per_adv, ISO_LINK_BCAST, BT_BOUND, &data); /* Queue start periodic advertising and create BIG */ @@ -2953,7 +2960,8 @@ void hci_conn_tx_queue(struct hci_conn *conn, struct sk_buff *skb) * TODO: SCO support without flowctl (needs to be done in drivers) */ switch (conn->type) { - case ISO_LINK: + case ISO_LINK_UCAST: + case ISO_LINK_BCAST: case ACL_LINK: case LE_LINK: break; diff --git a/net/bluetooth/hci_core.c b/net/bluetooth/hci_core.c index a58fd3bf8851..0c4b07115563 100644 --- a/net/bluetooth/hci_core.c +++ b/net/bluetooth/hci_core.c @@ -2898,12 +2898,13 @@ int hci_recv_frame(struct hci_dev *hdev, struct sk_buff *skb) break; case HCI_ACLDATA_PKT: /* Detect if ISO packet has been sent as ACL */ - if (hci_conn_num(hdev, ISO_LINK)) { + if (hci_conn_num(hdev, ISO_LINK_UCAST) || + hci_conn_num(hdev, ISO_LINK_BCAST)) { __u16 handle = __le16_to_cpu(hci_acl_hdr(skb)->handle); __u8 type; type = hci_conn_lookup_type(hdev, hci_handle(handle)); - if (type == ISO_LINK) + if (type == ISO_LINK_UCAST || type == ISO_LINK_BCAST) hci_skb_pkt_type(skb) = HCI_ISODATA_PKT; } break; @@ -3356,7 +3357,8 @@ static inline void hci_quote_sent(struct hci_conn *conn, int num, int *quote) case LE_LINK: cnt = hdev->le_mtu ? hdev->le_cnt : hdev->acl_cnt; break; - case ISO_LINK: + case ISO_LINK_UCAST: + case ISO_LINK_BCAST: cnt = hdev->iso_mtu ? hdev->iso_cnt : hdev->le_mtu ? hdev->le_cnt : hdev->acl_cnt; break; @@ -3370,7 +3372,7 @@ static inline void hci_quote_sent(struct hci_conn *conn, int num, int *quote) } static struct hci_conn *hci_low_sent(struct hci_dev *hdev, __u8 type, - int *quote) + __u8 type2, int *quote) { struct hci_conn_hash *h = &hdev->conn_hash; struct hci_conn *conn = NULL, *c; @@ -3382,7 +3384,8 @@ static struct hci_conn *hci_low_sent(struct hci_dev *hdev, __u8 type, rcu_read_lock(); list_for_each_entry_rcu(c, &h->list, list) { - if (c->type != type || skb_queue_empty(&c->data_q)) + if ((c->type != type && c->type != type2) || + skb_queue_empty(&c->data_q)) continue; if (c->state != BT_CONNECTED && c->state != BT_CONFIG) @@ -3590,7 +3593,7 @@ static void hci_sched_sco(struct hci_dev *hdev, __u8 type) else cnt = &hdev->sco_cnt; - while (*cnt && (conn = hci_low_sent(hdev, type, "e))) { + while (*cnt && (conn = hci_low_sent(hdev, type, type, "e))) { while (quote-- && (skb = skb_dequeue(&conn->data_q))) { BT_DBG("skb %p len %d", skb, skb->len); hci_send_conn_frame(hdev, conn, skb); @@ -3718,12 +3721,14 @@ static void hci_sched_iso(struct hci_dev *hdev) BT_DBG("%s", hdev->name); - if (!hci_conn_num(hdev, ISO_LINK)) + if (!hci_conn_num(hdev, ISO_LINK_UCAST) && + !hci_conn_num(hdev, ISO_LINK_BCAST)) return; cnt = hdev->iso_pkts ? &hdev->iso_cnt : hdev->le_pkts ? &hdev->le_cnt : &hdev->acl_cnt; - while (*cnt && (conn = hci_low_sent(hdev, ISO_LINK, "e))) { + while (*cnt && (conn = hci_low_sent(hdev, ISO_LINK_UCAST, + ISO_LINK_BCAST, "e))) { while (quote-- && (skb = skb_dequeue(&conn->data_q))) { BT_DBG("skb %p len %d", skb, skb->len); hci_send_conn_frame(hdev, conn, skb); diff --git a/net/bluetooth/hci_event.c b/net/bluetooth/hci_event.c index 105d1446c9dc..6ecf36afaae0 100644 --- a/net/bluetooth/hci_event.c +++ b/net/bluetooth/hci_event.c @@ -3793,7 +3793,7 @@ static void hci_unbound_cis_failed(struct hci_dev *hdev, u8 cig, u8 status) lockdep_assert_held(&hdev->lock); list_for_each_entry_safe(conn, tmp, &hdev->conn_hash.list, list) { - if (conn->type != ISO_LINK || !bacmp(&conn->dst, BDADDR_ANY) || + if (conn->type != ISO_LINK_UCAST || conn->state == BT_OPEN || conn->iso_qos.ucast.cig != cig) continue; @@ -4456,7 +4456,8 @@ static void hci_num_comp_pkts_evt(struct hci_dev *hdev, void *data, break; - case ISO_LINK: + case ISO_LINK_UCAST: + case ISO_LINK_BCAST: if (hdev->iso_pkts) { hdev->iso_cnt += count; if (hdev->iso_cnt > hdev->iso_pkts) @@ -6402,7 +6403,8 @@ static void hci_le_pa_sync_estabilished_evt(struct hci_dev *hdev, void *data, conn->sync_handle = le16_to_cpu(ev->handle); conn->sid = HCI_SID_INVALID; - mask |= hci_proto_connect_ind(hdev, &ev->bdaddr, ISO_LINK, &flags); + mask |= hci_proto_connect_ind(hdev, &ev->bdaddr, ISO_LINK_BCAST, + &flags); if (!(mask & HCI_LM_ACCEPT)) { hci_le_pa_term_sync(hdev, ev->handle); goto unlock; @@ -6412,7 +6414,7 @@ static void hci_le_pa_sync_estabilished_evt(struct hci_dev *hdev, void *data, goto unlock; /* Add connection to indicate PA sync event */ - pa_sync = hci_conn_add_unset(hdev, ISO_LINK, BDADDR_ANY, + pa_sync = hci_conn_add_unset(hdev, ISO_LINK_BCAST, BDADDR_ANY, HCI_ROLE_SLAVE); if (IS_ERR(pa_sync)) @@ -6443,7 +6445,7 @@ static void hci_le_per_adv_report_evt(struct hci_dev *hdev, void *data, hci_dev_lock(hdev); - mask |= hci_proto_connect_ind(hdev, BDADDR_ANY, ISO_LINK, &flags); + mask |= hci_proto_connect_ind(hdev, BDADDR_ANY, ISO_LINK_BCAST, &flags); if (!(mask & HCI_LM_ACCEPT)) goto unlock; @@ -6727,7 +6729,7 @@ static void hci_le_cis_estabilished_evt(struct hci_dev *hdev, void *data, goto unlock; } - if (conn->type != ISO_LINK) { + if (conn->type != ISO_LINK_UCAST) { bt_dev_err(hdev, "Invalid connection link type handle 0x%4.4x", handle); @@ -6845,7 +6847,7 @@ static void hci_le_cis_req_evt(struct hci_dev *hdev, void *data, if (!acl) goto unlock; - mask = hci_proto_connect_ind(hdev, &acl->dst, ISO_LINK, &flags); + mask = hci_proto_connect_ind(hdev, &acl->dst, ISO_LINK_UCAST, &flags); if (!(mask & HCI_LM_ACCEPT)) { hci_le_reject_cis(hdev, ev->cis_handle); goto unlock; @@ -6853,8 +6855,8 @@ static void hci_le_cis_req_evt(struct hci_dev *hdev, void *data, cis = hci_conn_hash_lookup_handle(hdev, cis_handle); if (!cis) { - cis = hci_conn_add(hdev, ISO_LINK, &acl->dst, HCI_ROLE_SLAVE, - cis_handle); + cis = hci_conn_add(hdev, ISO_LINK_UCAST, &acl->dst, + HCI_ROLE_SLAVE, cis_handle); if (IS_ERR(cis)) { hci_le_reject_cis(hdev, ev->cis_handle); goto unlock; @@ -6969,7 +6971,7 @@ static void hci_le_big_sync_established_evt(struct hci_dev *hdev, void *data, bt_dev_dbg(hdev, "ignore too large handle %u", handle); continue; } - bis = hci_conn_add(hdev, ISO_LINK, BDADDR_ANY, + bis = hci_conn_add(hdev, ISO_LINK_BCAST, BDADDR_ANY, HCI_ROLE_SLAVE, handle); if (IS_ERR(bis)) continue; @@ -7025,7 +7027,7 @@ static void hci_le_big_info_adv_report_evt(struct hci_dev *hdev, void *data, hci_dev_lock(hdev); - mask |= hci_proto_connect_ind(hdev, BDADDR_ANY, ISO_LINK, &flags); + mask |= hci_proto_connect_ind(hdev, BDADDR_ANY, ISO_LINK_BCAST, &flags); if (!(mask & HCI_LM_ACCEPT)) goto unlock; diff --git a/net/bluetooth/hci_sync.c b/net/bluetooth/hci_sync.c index d00ff18f3be0..5f37335140a9 100644 --- a/net/bluetooth/hci_sync.c +++ b/net/bluetooth/hci_sync.c @@ -2860,7 +2860,7 @@ static int hci_le_set_ext_scan_param_sync(struct hci_dev *hdev, u8 type, if (sent) { struct hci_conn *conn; - conn = hci_conn_hash_lookup_ba(hdev, ISO_LINK, + conn = hci_conn_hash_lookup_ba(hdev, ISO_LINK_BCAST, &sent->bdaddr); if (conn) { struct bt_iso_qos *qos = &conn->iso_qos; @@ -5477,7 +5477,7 @@ static int hci_connect_cancel_sync(struct hci_dev *hdev, struct hci_conn *conn, if (conn->type == LE_LINK) return hci_le_connect_cancel_sync(hdev, conn, reason); - if (conn->type == ISO_LINK) { + if (conn->type == ISO_LINK_UCAST) { /* BLUETOOTH CORE SPECIFICATION Version 5.3 | Vol 4, Part E * page 1857: * @@ -5490,9 +5490,10 @@ static int hci_connect_cancel_sync(struct hci_dev *hdev, struct hci_conn *conn, return hci_disconnect_sync(hdev, conn, reason); /* CIS with no Create CIS sent have nothing to cancel */ - if (bacmp(&conn->dst, BDADDR_ANY)) - return HCI_ERROR_LOCAL_HOST_TERM; + return HCI_ERROR_LOCAL_HOST_TERM; + } + if (conn->type == ISO_LINK_BCAST) { /* There is no way to cancel a BIS without terminating the BIG * which is done later on connection cleanup. */ @@ -5554,9 +5555,12 @@ static int hci_reject_conn_sync(struct hci_dev *hdev, struct hci_conn *conn, { struct hci_cp_reject_conn_req cp; - if (conn->type == ISO_LINK) + if (conn->type == ISO_LINK_UCAST) return hci_le_reject_cis_sync(hdev, conn, reason); + if (conn->type == ISO_LINK_BCAST) + return -EINVAL; + if (conn->type == SCO_LINK || conn->type == ESCO_LINK) return hci_reject_sco_sync(hdev, conn, reason); @@ -6917,7 +6921,7 @@ static void create_pa_complete(struct hci_dev *hdev, void *data, int err) goto unlock; /* Add connection to indicate PA sync error */ - pa_sync = hci_conn_add_unset(hdev, ISO_LINK, BDADDR_ANY, + pa_sync = hci_conn_add_unset(hdev, ISO_LINK_BCAST, BDADDR_ANY, HCI_ROLE_SLAVE); if (IS_ERR(pa_sync)) diff --git a/net/bluetooth/iso.c b/net/bluetooth/iso.c index 2f348f48e99d..608c8bf72128 100644 --- a/net/bluetooth/iso.c +++ b/net/bluetooth/iso.c @@ -2219,7 +2219,7 @@ int iso_connect_ind(struct hci_dev *hdev, bdaddr_t *bdaddr, __u8 *flags) static void iso_connect_cfm(struct hci_conn *hcon, __u8 status) { - if (hcon->type != ISO_LINK) { + if (hcon->type != ISO_LINK_UCAST && hcon->type != ISO_LINK_BCAST) { if (hcon->type != LE_LINK) return; @@ -2260,7 +2260,7 @@ static void iso_connect_cfm(struct hci_conn *hcon, __u8 status) static void iso_disconn_cfm(struct hci_conn *hcon, __u8 reason) { - if (hcon->type != ISO_LINK) + if (hcon->type != ISO_LINK_UCAST && hcon->type != ISO_LINK_BCAST) return; BT_DBG("hcon %p reason %d", hcon, reason); diff --git a/net/bluetooth/mgmt.c b/net/bluetooth/mgmt.c index 46b22708dfbd..26700394349c 100644 --- a/net/bluetooth/mgmt.c +++ b/net/bluetooth/mgmt.c @@ -3221,7 +3221,8 @@ static int disconnect(struct sock *sk, struct hci_dev *hdev, void *data, static u8 link_to_bdaddr(u8 link_type, u8 addr_type) { switch (link_type) { - case ISO_LINK: + case ISO_LINK_UCAST: + case ISO_LINK_BCAST: case LE_LINK: switch (addr_type) { case ADDR_LE_DEV_PUBLIC:
Use separate link type id for unicast and broadcast ISO connections. These connection types are handled with separate HCI commands, socket API is different, and hci_conn has union fields that are different in the two cases, so they shall not be mixed up. Currently in most places it is attempted to distinguish ucast by bacmp(&c->dst, BDADDR_ANY) but it is wrong as dst is set for bcast sink hci_conn in iso_conn_ready(). Additionally checking sync_handle might be OK, but depends on details of bcast conn configuration flow. To avoid complicating it, use separate link types. Fixes: f764a6c2c1e4 ("Bluetooth: ISO: Add broadcast support") Signed-off-by: Pauli Virtanen <pav@iki.fi> --- Notes: Although in theory this should be OK, bcast functionality is untested with this patch, aside from passing iso-tester. include/net/bluetooth/hci.h | 3 +- include/net/bluetooth/hci_core.h | 48 ++++++++++++++------------------ net/bluetooth/hci_conn.c | 44 +++++++++++++++++------------ net/bluetooth/hci_core.c | 21 ++++++++------ net/bluetooth/hci_event.c | 24 ++++++++-------- net/bluetooth/hci_sync.c | 16 +++++++---- net/bluetooth/iso.c | 4 +-- net/bluetooth/mgmt.c | 3 +- 8 files changed, 89 insertions(+), 74 deletions(-)