Bluetooth: ISO: Attempt to resolve broadcast address
Broadcasters maybe using RPAs which can change over time and not matching the address used as destination in the socket, so this attempts to resolve the addresses then match with the socket address, in case that uses an indentity address, or then match the IRKs if both broadcaster and socket are using RPAs. Signed-off-by: Luiz Augusto von Dentz <luiz.von.dentz@intel.com>pull/1354/merge
parent
14b06c3a88
commit
f817db10dc
|
|
@ -87,8 +87,8 @@ static void iso_sock_disconn(struct sock *sk);
|
||||||
|
|
||||||
typedef bool (*iso_sock_match_t)(struct sock *sk, void *data);
|
typedef bool (*iso_sock_match_t)(struct sock *sk, void *data);
|
||||||
|
|
||||||
static struct sock *iso_get_sock(bdaddr_t *src, bdaddr_t *dst,
|
static struct sock *iso_get_sock(struct hci_dev *hdev, bdaddr_t *src,
|
||||||
enum bt_sock_state state,
|
bdaddr_t *dst, enum bt_sock_state state,
|
||||||
iso_sock_match_t match, void *data);
|
iso_sock_match_t match, void *data);
|
||||||
|
|
||||||
/* ---- ISO timers ---- */
|
/* ---- ISO timers ---- */
|
||||||
|
|
@ -638,8 +638,8 @@ static struct sock *__iso_get_sock_listen_by_sid(bdaddr_t *ba, bdaddr_t *bc,
|
||||||
* match func data - pass -1 to ignore
|
* match func data - pass -1 to ignore
|
||||||
* Returns closest match.
|
* Returns closest match.
|
||||||
*/
|
*/
|
||||||
static struct sock *iso_get_sock(bdaddr_t *src, bdaddr_t *dst,
|
static struct sock *iso_get_sock(struct hci_dev *hdev, bdaddr_t *src,
|
||||||
enum bt_sock_state state,
|
bdaddr_t *dst, enum bt_sock_state state,
|
||||||
iso_sock_match_t match, void *data)
|
iso_sock_match_t match, void *data)
|
||||||
{
|
{
|
||||||
struct sock *sk = NULL, *sk1 = NULL;
|
struct sock *sk = NULL, *sk1 = NULL;
|
||||||
|
|
@ -651,9 +651,26 @@ static struct sock *iso_get_sock(bdaddr_t *src, bdaddr_t *dst,
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
/* Match Broadcast destination */
|
/* Match Broadcast destination */
|
||||||
if (bacmp(dst, BDADDR_ANY) && bacmp(&iso_pi(sk)->dst, dst))
|
if (bacmp(dst, BDADDR_ANY) && bacmp(&iso_pi(sk)->dst, dst)) {
|
||||||
|
struct smp_irk *irk1, *irk2;
|
||||||
|
|
||||||
|
/* Check if destination is an RPA that we can resolve */
|
||||||
|
irk1 = hci_find_irk_by_rpa(hdev, dst);
|
||||||
|
if (!irk1)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
|
/* Match with identity address */
|
||||||
|
if (bacmp(&iso_pi(sk)->dst, &irk1->bdaddr)) {
|
||||||
|
/* Check if socket destination address is also
|
||||||
|
* an RPA and if the IRK matches.
|
||||||
|
*/
|
||||||
|
irk2 = hci_find_irk_by_rpa(hdev,
|
||||||
|
&iso_pi(sk)->dst);
|
||||||
|
if (!irk2 || irk1 != irk2)
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/* Use Match function if provided */
|
/* Use Match function if provided */
|
||||||
if (match && !match(sk, data))
|
if (match && !match(sk, data))
|
||||||
continue;
|
continue;
|
||||||
|
|
@ -2012,6 +2029,7 @@ static void iso_conn_ready(struct iso_conn *conn)
|
||||||
struct hci_ev_le_pa_sync_established *ev2 = NULL;
|
struct hci_ev_le_pa_sync_established *ev2 = NULL;
|
||||||
struct hci_ev_le_per_adv_report *ev3 = NULL;
|
struct hci_ev_le_per_adv_report *ev3 = NULL;
|
||||||
struct hci_conn *hcon;
|
struct hci_conn *hcon;
|
||||||
|
struct hci_dev *hdev;
|
||||||
|
|
||||||
BT_DBG("conn %p", conn);
|
BT_DBG("conn %p", conn);
|
||||||
|
|
||||||
|
|
@ -2022,13 +2040,15 @@ static void iso_conn_ready(struct iso_conn *conn)
|
||||||
if (!hcon)
|
if (!hcon)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
|
hdev = hcon->hdev;
|
||||||
|
|
||||||
if (test_bit(HCI_CONN_BIG_SYNC, &hcon->flags)) {
|
if (test_bit(HCI_CONN_BIG_SYNC, &hcon->flags)) {
|
||||||
/* A BIS slave hcon is notified to the ISO layer
|
/* A BIS slave hcon is notified to the ISO layer
|
||||||
* after the Command Complete for the LE Setup
|
* after the Command Complete for the LE Setup
|
||||||
* ISO Data Path command is received. Get the
|
* ISO Data Path command is received. Get the
|
||||||
* parent socket that matches the hcon BIG handle.
|
* parent socket that matches the hcon BIG handle.
|
||||||
*/
|
*/
|
||||||
parent = iso_get_sock(&hcon->src, &hcon->dst,
|
parent = iso_get_sock(hdev, &hcon->src, &hcon->dst,
|
||||||
BT_LISTEN, iso_match_big_hcon,
|
BT_LISTEN, iso_match_big_hcon,
|
||||||
hcon);
|
hcon);
|
||||||
} else if (test_bit(HCI_CONN_BIG_SYNC_FAILED, &hcon->flags)) {
|
} else if (test_bit(HCI_CONN_BIG_SYNC_FAILED, &hcon->flags)) {
|
||||||
|
|
@ -2036,12 +2056,12 @@ static void iso_conn_ready(struct iso_conn *conn)
|
||||||
HCI_EVT_LE_BIG_SYNC_ESTABLISHED);
|
HCI_EVT_LE_BIG_SYNC_ESTABLISHED);
|
||||||
|
|
||||||
/* Get reference to PA sync parent socket, if it exists */
|
/* Get reference to PA sync parent socket, if it exists */
|
||||||
parent = iso_get_sock(&hcon->src, &hcon->dst,
|
parent = iso_get_sock(hdev, &hcon->src, &hcon->dst,
|
||||||
BT_LISTEN,
|
BT_LISTEN,
|
||||||
iso_match_pa_sync_flag,
|
iso_match_pa_sync_flag,
|
||||||
NULL);
|
NULL);
|
||||||
if (!parent && ev)
|
if (!parent && ev)
|
||||||
parent = iso_get_sock(&hcon->src,
|
parent = iso_get_sock(hdev, &hcon->src,
|
||||||
&hcon->dst,
|
&hcon->dst,
|
||||||
BT_LISTEN,
|
BT_LISTEN,
|
||||||
iso_match_big, ev);
|
iso_match_big, ev);
|
||||||
|
|
@ -2049,7 +2069,7 @@ static void iso_conn_ready(struct iso_conn *conn)
|
||||||
ev2 = hci_recv_event_data(hcon->hdev,
|
ev2 = hci_recv_event_data(hcon->hdev,
|
||||||
HCI_EV_LE_PA_SYNC_ESTABLISHED);
|
HCI_EV_LE_PA_SYNC_ESTABLISHED);
|
||||||
if (ev2)
|
if (ev2)
|
||||||
parent = iso_get_sock(&hcon->src,
|
parent = iso_get_sock(hdev, &hcon->src,
|
||||||
&hcon->dst,
|
&hcon->dst,
|
||||||
BT_LISTEN,
|
BT_LISTEN,
|
||||||
iso_match_sid, ev2);
|
iso_match_sid, ev2);
|
||||||
|
|
@ -2057,7 +2077,7 @@ static void iso_conn_ready(struct iso_conn *conn)
|
||||||
ev3 = hci_recv_event_data(hcon->hdev,
|
ev3 = hci_recv_event_data(hcon->hdev,
|
||||||
HCI_EV_LE_PER_ADV_REPORT);
|
HCI_EV_LE_PER_ADV_REPORT);
|
||||||
if (ev3)
|
if (ev3)
|
||||||
parent = iso_get_sock(&hcon->src,
|
parent = iso_get_sock(hdev, &hcon->src,
|
||||||
&hcon->dst,
|
&hcon->dst,
|
||||||
BT_LISTEN,
|
BT_LISTEN,
|
||||||
iso_match_sync_handle_pa_report,
|
iso_match_sync_handle_pa_report,
|
||||||
|
|
@ -2065,7 +2085,7 @@ static void iso_conn_ready(struct iso_conn *conn)
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!parent)
|
if (!parent)
|
||||||
parent = iso_get_sock(&hcon->src, BDADDR_ANY,
|
parent = iso_get_sock(hdev, &hcon->src, BDADDR_ANY,
|
||||||
BT_LISTEN, NULL, NULL);
|
BT_LISTEN, NULL, NULL);
|
||||||
|
|
||||||
if (!parent)
|
if (!parent)
|
||||||
|
|
@ -2208,7 +2228,7 @@ int iso_connect_ind(struct hci_dev *hdev, bdaddr_t *bdaddr, __u8 *flags)
|
||||||
*/
|
*/
|
||||||
ev1 = hci_recv_event_data(hdev, HCI_EV_LE_PA_SYNC_ESTABLISHED);
|
ev1 = hci_recv_event_data(hdev, HCI_EV_LE_PA_SYNC_ESTABLISHED);
|
||||||
if (ev1) {
|
if (ev1) {
|
||||||
sk = iso_get_sock(&hdev->bdaddr, bdaddr, BT_LISTEN,
|
sk = iso_get_sock(hdev, &hdev->bdaddr, bdaddr, BT_LISTEN,
|
||||||
iso_match_sid, ev1);
|
iso_match_sid, ev1);
|
||||||
if (sk && !ev1->status) {
|
if (sk && !ev1->status) {
|
||||||
iso_pi(sk)->sync_handle = le16_to_cpu(ev1->handle);
|
iso_pi(sk)->sync_handle = le16_to_cpu(ev1->handle);
|
||||||
|
|
@ -2220,7 +2240,7 @@ int iso_connect_ind(struct hci_dev *hdev, bdaddr_t *bdaddr, __u8 *flags)
|
||||||
|
|
||||||
ev1a = hci_recv_event_data(hdev, HCI_EV_LE_PAST_RECEIVED);
|
ev1a = hci_recv_event_data(hdev, HCI_EV_LE_PAST_RECEIVED);
|
||||||
if (ev1a) {
|
if (ev1a) {
|
||||||
sk = iso_get_sock(&hdev->bdaddr, bdaddr, BT_LISTEN,
|
sk = iso_get_sock(hdev, &hdev->bdaddr, bdaddr, BT_LISTEN,
|
||||||
iso_match_sid_past, ev1a);
|
iso_match_sid_past, ev1a);
|
||||||
if (sk && !ev1a->status) {
|
if (sk && !ev1a->status) {
|
||||||
iso_pi(sk)->sync_handle = le16_to_cpu(ev1a->sync_handle);
|
iso_pi(sk)->sync_handle = le16_to_cpu(ev1a->sync_handle);
|
||||||
|
|
@ -2233,7 +2253,7 @@ int iso_connect_ind(struct hci_dev *hdev, bdaddr_t *bdaddr, __u8 *flags)
|
||||||
ev2 = hci_recv_event_data(hdev, HCI_EVT_LE_BIG_INFO_ADV_REPORT);
|
ev2 = hci_recv_event_data(hdev, HCI_EVT_LE_BIG_INFO_ADV_REPORT);
|
||||||
if (ev2) {
|
if (ev2) {
|
||||||
/* Check if BIGInfo report has already been handled */
|
/* Check if BIGInfo report has already been handled */
|
||||||
sk = iso_get_sock(&hdev->bdaddr, bdaddr, BT_CONNECTED,
|
sk = iso_get_sock(hdev, &hdev->bdaddr, bdaddr, BT_CONNECTED,
|
||||||
iso_match_sync_handle, ev2);
|
iso_match_sync_handle, ev2);
|
||||||
if (sk) {
|
if (sk) {
|
||||||
sock_put(sk);
|
sock_put(sk);
|
||||||
|
|
@ -2242,10 +2262,10 @@ int iso_connect_ind(struct hci_dev *hdev, bdaddr_t *bdaddr, __u8 *flags)
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Try to get PA sync socket, if it exists */
|
/* Try to get PA sync socket, if it exists */
|
||||||
sk = iso_get_sock(&hdev->bdaddr, bdaddr, BT_CONNECT2,
|
sk = iso_get_sock(hdev, &hdev->bdaddr, bdaddr, BT_CONNECT2,
|
||||||
iso_match_sync_handle, ev2);
|
iso_match_sync_handle, ev2);
|
||||||
if (!sk)
|
if (!sk)
|
||||||
sk = iso_get_sock(&hdev->bdaddr, bdaddr,
|
sk = iso_get_sock(hdev, &hdev->bdaddr, bdaddr,
|
||||||
BT_LISTEN,
|
BT_LISTEN,
|
||||||
iso_match_sync_handle,
|
iso_match_sync_handle,
|
||||||
ev2);
|
ev2);
|
||||||
|
|
@ -2284,7 +2304,7 @@ int iso_connect_ind(struct hci_dev *hdev, bdaddr_t *bdaddr, __u8 *flags)
|
||||||
u8 *base;
|
u8 *base;
|
||||||
struct hci_conn *hcon;
|
struct hci_conn *hcon;
|
||||||
|
|
||||||
sk = iso_get_sock(&hdev->bdaddr, bdaddr, BT_LISTEN,
|
sk = iso_get_sock(hdev, &hdev->bdaddr, bdaddr, BT_LISTEN,
|
||||||
iso_match_sync_handle_pa_report, ev3);
|
iso_match_sync_handle_pa_report, ev3);
|
||||||
if (!sk)
|
if (!sk)
|
||||||
goto done;
|
goto done;
|
||||||
|
|
@ -2334,7 +2354,7 @@ int iso_connect_ind(struct hci_dev *hdev, bdaddr_t *bdaddr, __u8 *flags)
|
||||||
hcon->le_per_adv_data_len = 0;
|
hcon->le_per_adv_data_len = 0;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
sk = iso_get_sock(&hdev->bdaddr, BDADDR_ANY,
|
sk = iso_get_sock(hdev, &hdev->bdaddr, BDADDR_ANY,
|
||||||
BT_LISTEN, NULL, NULL);
|
BT_LISTEN, NULL, NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue