Bluetooth: HCI: Always use the identity address when initializing a connection
This makes sure hci_conn is initialized with the identity address if a matching IRK exists which avoids the trouble of having to do it at multiple places which seems to be missing (e.g. CIS, BIS and PA). Signed-off-by: Luiz Augusto von Dentz <luiz.von.dentz@intel.com>pull/1354/merge
parent
d3413703d5
commit
14b06c3a88
|
|
@ -1571,9 +1571,9 @@ int hci_le_create_cis_pending(struct hci_dev *hdev);
|
||||||
int hci_conn_check_create_cis(struct hci_conn *conn);
|
int hci_conn_check_create_cis(struct hci_conn *conn);
|
||||||
|
|
||||||
struct hci_conn *hci_conn_add(struct hci_dev *hdev, int type, bdaddr_t *dst,
|
struct hci_conn *hci_conn_add(struct hci_dev *hdev, int type, bdaddr_t *dst,
|
||||||
u8 role, u16 handle);
|
u8 dst_type, u8 role, u16 handle);
|
||||||
struct hci_conn *hci_conn_add_unset(struct hci_dev *hdev, int type,
|
struct hci_conn *hci_conn_add_unset(struct hci_dev *hdev, int type,
|
||||||
bdaddr_t *dst, u8 role);
|
bdaddr_t *dst, u8 dst_type, u8 role);
|
||||||
void hci_conn_del(struct hci_conn *conn);
|
void hci_conn_del(struct hci_conn *conn);
|
||||||
void hci_conn_hash_flush(struct hci_dev *hdev);
|
void hci_conn_hash_flush(struct hci_dev *hdev);
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -922,10 +922,12 @@ static int hci_conn_hash_alloc_unset(struct hci_dev *hdev)
|
||||||
U16_MAX, GFP_ATOMIC);
|
U16_MAX, GFP_ATOMIC);
|
||||||
}
|
}
|
||||||
|
|
||||||
static struct hci_conn *__hci_conn_add(struct hci_dev *hdev, int type, bdaddr_t *dst,
|
static struct hci_conn *__hci_conn_add(struct hci_dev *hdev, int type,
|
||||||
|
bdaddr_t *dst, u8 dst_type,
|
||||||
u8 role, u16 handle)
|
u8 role, u16 handle)
|
||||||
{
|
{
|
||||||
struct hci_conn *conn;
|
struct hci_conn *conn;
|
||||||
|
struct smp_irk *irk = NULL;
|
||||||
|
|
||||||
switch (type) {
|
switch (type) {
|
||||||
case ACL_LINK:
|
case ACL_LINK:
|
||||||
|
|
@ -937,12 +939,14 @@ static struct hci_conn *__hci_conn_add(struct hci_dev *hdev, int type, bdaddr_t
|
||||||
case PA_LINK:
|
case PA_LINK:
|
||||||
if (!hdev->iso_mtu)
|
if (!hdev->iso_mtu)
|
||||||
return ERR_PTR(-ECONNREFUSED);
|
return ERR_PTR(-ECONNREFUSED);
|
||||||
|
irk = hci_get_irk(hdev, dst, dst_type);
|
||||||
break;
|
break;
|
||||||
case LE_LINK:
|
case LE_LINK:
|
||||||
if (hdev->le_mtu && hdev->le_mtu < HCI_MIN_LE_MTU)
|
if (hdev->le_mtu && hdev->le_mtu < HCI_MIN_LE_MTU)
|
||||||
return ERR_PTR(-ECONNREFUSED);
|
return ERR_PTR(-ECONNREFUSED);
|
||||||
if (!hdev->le_mtu && hdev->acl_mtu < HCI_MIN_LE_MTU)
|
if (!hdev->le_mtu && hdev->acl_mtu < HCI_MIN_LE_MTU)
|
||||||
return ERR_PTR(-ECONNREFUSED);
|
return ERR_PTR(-ECONNREFUSED);
|
||||||
|
irk = hci_get_irk(hdev, dst, dst_type);
|
||||||
break;
|
break;
|
||||||
case SCO_LINK:
|
case SCO_LINK:
|
||||||
case ESCO_LINK:
|
case ESCO_LINK:
|
||||||
|
|
@ -960,7 +964,15 @@ static struct hci_conn *__hci_conn_add(struct hci_dev *hdev, int type, bdaddr_t
|
||||||
if (!conn)
|
if (!conn)
|
||||||
return ERR_PTR(-ENOMEM);
|
return ERR_PTR(-ENOMEM);
|
||||||
|
|
||||||
|
/* If and IRK exists use its identity address */
|
||||||
|
if (!irk) {
|
||||||
bacpy(&conn->dst, dst);
|
bacpy(&conn->dst, dst);
|
||||||
|
conn->dst_type = dst_type;
|
||||||
|
} else {
|
||||||
|
bacpy(&conn->dst, &irk->bdaddr);
|
||||||
|
conn->dst_type = irk->addr_type;
|
||||||
|
}
|
||||||
|
|
||||||
bacpy(&conn->src, &hdev->bdaddr);
|
bacpy(&conn->src, &hdev->bdaddr);
|
||||||
conn->handle = handle;
|
conn->handle = handle;
|
||||||
conn->hdev = hdev;
|
conn->hdev = hdev;
|
||||||
|
|
@ -1059,7 +1071,7 @@ static struct hci_conn *__hci_conn_add(struct hci_dev *hdev, int type, bdaddr_t
|
||||||
}
|
}
|
||||||
|
|
||||||
struct hci_conn *hci_conn_add_unset(struct hci_dev *hdev, int type,
|
struct hci_conn *hci_conn_add_unset(struct hci_dev *hdev, int type,
|
||||||
bdaddr_t *dst, u8 role)
|
bdaddr_t *dst, u8 dst_type, u8 role)
|
||||||
{
|
{
|
||||||
int handle;
|
int handle;
|
||||||
|
|
||||||
|
|
@ -1069,16 +1081,16 @@ struct hci_conn *hci_conn_add_unset(struct hci_dev *hdev, int type,
|
||||||
if (unlikely(handle < 0))
|
if (unlikely(handle < 0))
|
||||||
return ERR_PTR(-ECONNREFUSED);
|
return ERR_PTR(-ECONNREFUSED);
|
||||||
|
|
||||||
return __hci_conn_add(hdev, type, dst, role, handle);
|
return __hci_conn_add(hdev, type, dst, dst_type, role, handle);
|
||||||
}
|
}
|
||||||
|
|
||||||
struct hci_conn *hci_conn_add(struct hci_dev *hdev, int type, bdaddr_t *dst,
|
struct hci_conn *hci_conn_add(struct hci_dev *hdev, int type, bdaddr_t *dst,
|
||||||
u8 role, u16 handle)
|
u8 dst_type, u8 role, u16 handle)
|
||||||
{
|
{
|
||||||
if (handle > HCI_CONN_HANDLE_MAX)
|
if (handle > HCI_CONN_HANDLE_MAX)
|
||||||
return ERR_PTR(-EINVAL);
|
return ERR_PTR(-EINVAL);
|
||||||
|
|
||||||
return __hci_conn_add(hdev, type, dst, role, handle);
|
return __hci_conn_add(hdev, type, dst, dst_type, role, handle);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void hci_conn_cleanup_child(struct hci_conn *conn, u8 reason)
|
static void hci_conn_cleanup_child(struct hci_conn *conn, u8 reason)
|
||||||
|
|
@ -1410,14 +1422,13 @@ struct hci_conn *hci_connect_le(struct hci_dev *hdev, bdaddr_t *dst,
|
||||||
if (conn) {
|
if (conn) {
|
||||||
bacpy(&conn->dst, dst);
|
bacpy(&conn->dst, dst);
|
||||||
} else {
|
} else {
|
||||||
conn = hci_conn_add_unset(hdev, LE_LINK, dst, role);
|
conn = hci_conn_add_unset(hdev, LE_LINK, dst, dst_type, role);
|
||||||
if (IS_ERR(conn))
|
if (IS_ERR(conn))
|
||||||
return conn;
|
return conn;
|
||||||
hci_conn_hold(conn);
|
hci_conn_hold(conn);
|
||||||
conn->pending_sec_level = sec_level;
|
conn->pending_sec_level = sec_level;
|
||||||
}
|
}
|
||||||
|
|
||||||
conn->dst_type = dst_type;
|
|
||||||
conn->sec_level = BT_SECURITY_LOW;
|
conn->sec_level = BT_SECURITY_LOW;
|
||||||
conn->conn_timeout = conn_timeout;
|
conn->conn_timeout = conn_timeout;
|
||||||
conn->le_adv_phy = phy;
|
conn->le_adv_phy = phy;
|
||||||
|
|
@ -1587,7 +1598,7 @@ static struct hci_conn *hci_add_bis(struct hci_dev *hdev, bdaddr_t *dst,
|
||||||
memcmp(conn->le_per_adv_data, base, base_len)))
|
memcmp(conn->le_per_adv_data, base, base_len)))
|
||||||
return ERR_PTR(-EADDRINUSE);
|
return ERR_PTR(-EADDRINUSE);
|
||||||
|
|
||||||
conn = hci_conn_add_unset(hdev, BIS_LINK, dst, HCI_ROLE_MASTER);
|
conn = hci_conn_add_unset(hdev, BIS_LINK, dst, 0, HCI_ROLE_MASTER);
|
||||||
if (IS_ERR(conn))
|
if (IS_ERR(conn))
|
||||||
return conn;
|
return conn;
|
||||||
|
|
||||||
|
|
@ -1633,7 +1644,8 @@ struct hci_conn *hci_connect_le_scan(struct hci_dev *hdev, bdaddr_t *dst,
|
||||||
|
|
||||||
BT_DBG("requesting refresh of dst_addr");
|
BT_DBG("requesting refresh of dst_addr");
|
||||||
|
|
||||||
conn = hci_conn_add_unset(hdev, LE_LINK, dst, HCI_ROLE_MASTER);
|
conn = hci_conn_add_unset(hdev, LE_LINK, dst, dst_type,
|
||||||
|
HCI_ROLE_MASTER);
|
||||||
if (IS_ERR(conn))
|
if (IS_ERR(conn))
|
||||||
return conn;
|
return conn;
|
||||||
|
|
||||||
|
|
@ -1644,7 +1656,6 @@ struct hci_conn *hci_connect_le_scan(struct hci_dev *hdev, bdaddr_t *dst,
|
||||||
|
|
||||||
conn->state = BT_CONNECT;
|
conn->state = BT_CONNECT;
|
||||||
set_bit(HCI_CONN_SCANNING, &conn->flags);
|
set_bit(HCI_CONN_SCANNING, &conn->flags);
|
||||||
conn->dst_type = dst_type;
|
|
||||||
conn->sec_level = BT_SECURITY_LOW;
|
conn->sec_level = BT_SECURITY_LOW;
|
||||||
conn->pending_sec_level = sec_level;
|
conn->pending_sec_level = sec_level;
|
||||||
conn->conn_timeout = conn_timeout;
|
conn->conn_timeout = conn_timeout;
|
||||||
|
|
@ -1681,7 +1692,8 @@ struct hci_conn *hci_connect_acl(struct hci_dev *hdev, bdaddr_t *dst,
|
||||||
|
|
||||||
acl = hci_conn_hash_lookup_ba(hdev, ACL_LINK, dst);
|
acl = hci_conn_hash_lookup_ba(hdev, ACL_LINK, dst);
|
||||||
if (!acl) {
|
if (!acl) {
|
||||||
acl = hci_conn_add_unset(hdev, ACL_LINK, dst, HCI_ROLE_MASTER);
|
acl = hci_conn_add_unset(hdev, ACL_LINK, dst, 0,
|
||||||
|
HCI_ROLE_MASTER);
|
||||||
if (IS_ERR(acl))
|
if (IS_ERR(acl))
|
||||||
return acl;
|
return acl;
|
||||||
}
|
}
|
||||||
|
|
@ -1750,7 +1762,7 @@ struct hci_conn *hci_connect_sco(struct hci_dev *hdev, int type, bdaddr_t *dst,
|
||||||
|
|
||||||
sco = hci_conn_hash_lookup_ba(hdev, type, dst);
|
sco = hci_conn_hash_lookup_ba(hdev, type, dst);
|
||||||
if (!sco) {
|
if (!sco) {
|
||||||
sco = hci_conn_add_unset(hdev, type, dst, HCI_ROLE_MASTER);
|
sco = hci_conn_add_unset(hdev, type, dst, 0, HCI_ROLE_MASTER);
|
||||||
if (IS_ERR(sco)) {
|
if (IS_ERR(sco)) {
|
||||||
hci_conn_drop(acl);
|
hci_conn_drop(acl);
|
||||||
return sco;
|
return sco;
|
||||||
|
|
@ -1942,7 +1954,7 @@ 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,
|
cis = hci_conn_hash_lookup_cis(hdev, dst, dst_type, qos->ucast.cig,
|
||||||
qos->ucast.cis);
|
qos->ucast.cis);
|
||||||
if (!cis) {
|
if (!cis) {
|
||||||
cis = hci_conn_add_unset(hdev, CIS_LINK, dst,
|
cis = hci_conn_add_unset(hdev, CIS_LINK, dst, dst_type,
|
||||||
HCI_ROLE_MASTER);
|
HCI_ROLE_MASTER);
|
||||||
if (IS_ERR(cis))
|
if (IS_ERR(cis))
|
||||||
return cis;
|
return cis;
|
||||||
|
|
@ -2133,12 +2145,11 @@ 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);
|
bt_dev_dbg(hdev, "dst %pMR type %d sid %d", dst, dst_type, sid);
|
||||||
|
|
||||||
conn = hci_conn_add_unset(hdev, PA_LINK, dst, HCI_ROLE_SLAVE);
|
conn = hci_conn_add_unset(hdev, PA_LINK, dst, dst_type, HCI_ROLE_SLAVE);
|
||||||
if (IS_ERR(conn))
|
if (IS_ERR(conn))
|
||||||
return conn;
|
return conn;
|
||||||
|
|
||||||
conn->iso_qos = *qos;
|
conn->iso_qos = *qos;
|
||||||
conn->dst_type = dst_type;
|
|
||||||
conn->sid = sid;
|
conn->sid = sid;
|
||||||
conn->state = BT_LISTEN;
|
conn->state = BT_LISTEN;
|
||||||
conn->conn_timeout = msecs_to_jiffies(qos->bcast.sync_timeout * 10);
|
conn->conn_timeout = msecs_to_jiffies(qos->bcast.sync_timeout * 10);
|
||||||
|
|
|
||||||
|
|
@ -2267,7 +2267,7 @@ static void hci_cs_create_conn(struct hci_dev *hdev, __u8 status)
|
||||||
} else {
|
} else {
|
||||||
if (!conn) {
|
if (!conn) {
|
||||||
conn = hci_conn_add_unset(hdev, ACL_LINK, &cp->bdaddr,
|
conn = hci_conn_add_unset(hdev, ACL_LINK, &cp->bdaddr,
|
||||||
HCI_ROLE_MASTER);
|
0, HCI_ROLE_MASTER);
|
||||||
if (IS_ERR(conn))
|
if (IS_ERR(conn))
|
||||||
bt_dev_err(hdev, "connection err: %ld", PTR_ERR(conn));
|
bt_dev_err(hdev, "connection err: %ld", PTR_ERR(conn));
|
||||||
}
|
}
|
||||||
|
|
@ -3123,7 +3123,8 @@ static void hci_conn_complete_evt(struct hci_dev *hdev, void *data,
|
||||||
&ev->bdaddr,
|
&ev->bdaddr,
|
||||||
BDADDR_BREDR)) {
|
BDADDR_BREDR)) {
|
||||||
conn = hci_conn_add_unset(hdev, ev->link_type,
|
conn = hci_conn_add_unset(hdev, ev->link_type,
|
||||||
&ev->bdaddr, HCI_ROLE_SLAVE);
|
&ev->bdaddr, 0,
|
||||||
|
HCI_ROLE_SLAVE);
|
||||||
if (IS_ERR(conn)) {
|
if (IS_ERR(conn)) {
|
||||||
bt_dev_err(hdev, "connection err: %ld", PTR_ERR(conn));
|
bt_dev_err(hdev, "connection err: %ld", PTR_ERR(conn));
|
||||||
goto unlock;
|
goto unlock;
|
||||||
|
|
@ -3299,7 +3300,7 @@ static void hci_conn_request_evt(struct hci_dev *hdev, void *data,
|
||||||
conn = hci_conn_hash_lookup_ba(hdev, ev->link_type,
|
conn = hci_conn_hash_lookup_ba(hdev, ev->link_type,
|
||||||
&ev->bdaddr);
|
&ev->bdaddr);
|
||||||
if (!conn) {
|
if (!conn) {
|
||||||
conn = hci_conn_add_unset(hdev, ev->link_type, &ev->bdaddr,
|
conn = hci_conn_add_unset(hdev, ev->link_type, &ev->bdaddr, 0,
|
||||||
HCI_ROLE_SLAVE);
|
HCI_ROLE_SLAVE);
|
||||||
if (IS_ERR(conn)) {
|
if (IS_ERR(conn)) {
|
||||||
bt_dev_err(hdev, "connection err: %ld", PTR_ERR(conn));
|
bt_dev_err(hdev, "connection err: %ld", PTR_ERR(conn));
|
||||||
|
|
@ -5670,14 +5671,13 @@ static void le_conn_complete_evt(struct hci_dev *hdev, u8 status,
|
||||||
if (status)
|
if (status)
|
||||||
goto unlock;
|
goto unlock;
|
||||||
|
|
||||||
conn = hci_conn_add_unset(hdev, LE_LINK, bdaddr, role);
|
conn = hci_conn_add_unset(hdev, LE_LINK, bdaddr, bdaddr_type,
|
||||||
|
role);
|
||||||
if (IS_ERR(conn)) {
|
if (IS_ERR(conn)) {
|
||||||
bt_dev_err(hdev, "connection err: %ld", PTR_ERR(conn));
|
bt_dev_err(hdev, "connection err: %ld", PTR_ERR(conn));
|
||||||
goto unlock;
|
goto unlock;
|
||||||
}
|
}
|
||||||
|
|
||||||
conn->dst_type = bdaddr_type;
|
|
||||||
|
|
||||||
/* If we didn't have a hci_conn object previously
|
/* If we didn't have a hci_conn object previously
|
||||||
* but we're in central role this must be something
|
* but we're in central role this must be something
|
||||||
* initiated using an accept list. Since accept list based
|
* initiated using an accept list. Since accept list based
|
||||||
|
|
@ -5982,7 +5982,7 @@ static void hci_le_past_received_evt(struct hci_dev *hdev, void *data,
|
||||||
goto unlock;
|
goto unlock;
|
||||||
|
|
||||||
/* Add connection to indicate PA sync event */
|
/* Add connection to indicate PA sync event */
|
||||||
pa_sync = hci_conn_add_unset(hdev, PA_LINK, BDADDR_ANY,
|
pa_sync = hci_conn_add_unset(hdev, PA_LINK, BDADDR_ANY, 0,
|
||||||
HCI_ROLE_SLAVE);
|
HCI_ROLE_SLAVE);
|
||||||
|
|
||||||
if (IS_ERR(pa_sync))
|
if (IS_ERR(pa_sync))
|
||||||
|
|
@ -6515,7 +6515,7 @@ static void hci_le_pa_sync_established_evt(struct hci_dev *hdev, void *data,
|
||||||
goto unlock;
|
goto unlock;
|
||||||
|
|
||||||
/* Add connection to indicate PA sync event */
|
/* Add connection to indicate PA sync event */
|
||||||
pa_sync = hci_conn_add_unset(hdev, PA_LINK, BDADDR_ANY,
|
pa_sync = hci_conn_add_unset(hdev, PA_LINK, BDADDR_ANY, 0,
|
||||||
HCI_ROLE_SLAVE);
|
HCI_ROLE_SLAVE);
|
||||||
|
|
||||||
if (IS_ERR(pa_sync))
|
if (IS_ERR(pa_sync))
|
||||||
|
|
@ -6956,7 +6956,7 @@ static void hci_le_cis_req_evt(struct hci_dev *hdev, void *data,
|
||||||
|
|
||||||
cis = hci_conn_hash_lookup_handle(hdev, cis_handle);
|
cis = hci_conn_hash_lookup_handle(hdev, cis_handle);
|
||||||
if (!cis) {
|
if (!cis) {
|
||||||
cis = hci_conn_add(hdev, CIS_LINK, &acl->dst,
|
cis = hci_conn_add(hdev, CIS_LINK, &acl->dst, acl->dst_type,
|
||||||
HCI_ROLE_SLAVE, cis_handle);
|
HCI_ROLE_SLAVE, cis_handle);
|
||||||
if (IS_ERR(cis)) {
|
if (IS_ERR(cis)) {
|
||||||
hci_le_reject_cis(hdev, ev->cis_handle);
|
hci_le_reject_cis(hdev, ev->cis_handle);
|
||||||
|
|
@ -7073,7 +7073,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);
|
bt_dev_dbg(hdev, "ignore too large handle %u", handle);
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
bis = hci_conn_add(hdev, BIS_LINK, BDADDR_ANY,
|
bis = hci_conn_add(hdev, BIS_LINK, BDADDR_ANY, 0,
|
||||||
HCI_ROLE_SLAVE, handle);
|
HCI_ROLE_SLAVE, handle);
|
||||||
if (IS_ERR(bis))
|
if (IS_ERR(bis))
|
||||||
continue;
|
continue;
|
||||||
|
|
|
||||||
|
|
@ -7013,7 +7013,7 @@ static void create_pa_complete(struct hci_dev *hdev, void *data, int err)
|
||||||
goto unlock;
|
goto unlock;
|
||||||
|
|
||||||
/* Add connection to indicate PA sync error */
|
/* Add connection to indicate PA sync error */
|
||||||
pa_sync = hci_conn_add_unset(hdev, PA_LINK, BDADDR_ANY,
|
pa_sync = hci_conn_add_unset(hdev, PA_LINK, BDADDR_ANY, 0,
|
||||||
HCI_ROLE_SLAVE);
|
HCI_ROLE_SLAVE);
|
||||||
|
|
||||||
if (IS_ERR(pa_sync))
|
if (IS_ERR(pa_sync))
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue