Bluetooth: Introduce helpers for le conn status and complete
This is done so that the helpers can be used for extended conn implementation which will be done in subsequent patch. Signed-off-by: Jaganath Kanakkassery <jaganathx.kanakkassery@intel.com> Signed-off-by: Marcel Holtmann <marcel@holtmann.org>
This commit is contained in:
committed by
Marcel Holtmann
parent
c215e9397b
commit
d12fb05643
@@ -1971,10 +1971,44 @@ static void hci_cs_disconnect(struct hci_dev *hdev, u8 status)
|
|||||||
hci_dev_unlock(hdev);
|
hci_dev_unlock(hdev);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void cs_le_create_conn(struct hci_dev *hdev, bdaddr_t *peer_addr,
|
||||||
|
u8 peer_addr_type, u8 own_address_type,
|
||||||
|
u8 filter_policy)
|
||||||
|
{
|
||||||
|
struct hci_conn *conn;
|
||||||
|
|
||||||
|
conn = hci_conn_hash_lookup_le(hdev, peer_addr,
|
||||||
|
peer_addr_type);
|
||||||
|
if (!conn)
|
||||||
|
return;
|
||||||
|
|
||||||
|
/* Store the initiator and responder address information which
|
||||||
|
* is needed for SMP. These values will not change during the
|
||||||
|
* lifetime of the connection.
|
||||||
|
*/
|
||||||
|
conn->init_addr_type = own_address_type;
|
||||||
|
if (own_address_type == ADDR_LE_DEV_RANDOM)
|
||||||
|
bacpy(&conn->init_addr, &hdev->random_addr);
|
||||||
|
else
|
||||||
|
bacpy(&conn->init_addr, &hdev->bdaddr);
|
||||||
|
|
||||||
|
conn->resp_addr_type = peer_addr_type;
|
||||||
|
bacpy(&conn->resp_addr, peer_addr);
|
||||||
|
|
||||||
|
/* We don't want the connection attempt to stick around
|
||||||
|
* indefinitely since LE doesn't have a page timeout concept
|
||||||
|
* like BR/EDR. Set a timer for any connection that doesn't use
|
||||||
|
* the white list for connecting.
|
||||||
|
*/
|
||||||
|
if (filter_policy == HCI_LE_USE_PEER_ADDR)
|
||||||
|
queue_delayed_work(conn->hdev->workqueue,
|
||||||
|
&conn->le_conn_timeout,
|
||||||
|
conn->conn_timeout);
|
||||||
|
}
|
||||||
|
|
||||||
static void hci_cs_le_create_conn(struct hci_dev *hdev, u8 status)
|
static void hci_cs_le_create_conn(struct hci_dev *hdev, u8 status)
|
||||||
{
|
{
|
||||||
struct hci_cp_le_create_conn *cp;
|
struct hci_cp_le_create_conn *cp;
|
||||||
struct hci_conn *conn;
|
|
||||||
|
|
||||||
BT_DBG("%s status 0x%2.2x", hdev->name, status);
|
BT_DBG("%s status 0x%2.2x", hdev->name, status);
|
||||||
|
|
||||||
@@ -1991,35 +2025,9 @@ static void hci_cs_le_create_conn(struct hci_dev *hdev, u8 status)
|
|||||||
|
|
||||||
hci_dev_lock(hdev);
|
hci_dev_lock(hdev);
|
||||||
|
|
||||||
conn = hci_conn_hash_lookup_le(hdev, &cp->peer_addr,
|
cs_le_create_conn(hdev, &cp->peer_addr, cp->peer_addr_type,
|
||||||
cp->peer_addr_type);
|
cp->own_address_type, cp->filter_policy);
|
||||||
if (!conn)
|
|
||||||
goto unlock;
|
|
||||||
|
|
||||||
/* Store the initiator and responder address information which
|
|
||||||
* is needed for SMP. These values will not change during the
|
|
||||||
* lifetime of the connection.
|
|
||||||
*/
|
|
||||||
conn->init_addr_type = cp->own_address_type;
|
|
||||||
if (cp->own_address_type == ADDR_LE_DEV_RANDOM)
|
|
||||||
bacpy(&conn->init_addr, &hdev->random_addr);
|
|
||||||
else
|
|
||||||
bacpy(&conn->init_addr, &hdev->bdaddr);
|
|
||||||
|
|
||||||
conn->resp_addr_type = cp->peer_addr_type;
|
|
||||||
bacpy(&conn->resp_addr, &cp->peer_addr);
|
|
||||||
|
|
||||||
/* We don't want the connection attempt to stick around
|
|
||||||
* indefinitely since LE doesn't have a page timeout concept
|
|
||||||
* like BR/EDR. Set a timer for any connection that doesn't use
|
|
||||||
* the white list for connecting.
|
|
||||||
*/
|
|
||||||
if (cp->filter_policy == HCI_LE_USE_PEER_ADDR)
|
|
||||||
queue_delayed_work(conn->hdev->workqueue,
|
|
||||||
&conn->le_conn_timeout,
|
|
||||||
conn->conn_timeout);
|
|
||||||
|
|
||||||
unlock:
|
|
||||||
hci_dev_unlock(hdev);
|
hci_dev_unlock(hdev);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -4551,16 +4559,15 @@ static void hci_disconn_phylink_complete_evt(struct hci_dev *hdev,
|
|||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
static void hci_le_conn_complete_evt(struct hci_dev *hdev, struct sk_buff *skb)
|
static void le_conn_complete_evt(struct hci_dev *hdev, u8 status,
|
||||||
|
bdaddr_t *bdaddr, u8 bdaddr_type, u8 role, u16 handle,
|
||||||
|
u16 interval, u16 latency, u16 supervision_timeout)
|
||||||
{
|
{
|
||||||
struct hci_ev_le_conn_complete *ev = (void *) skb->data;
|
|
||||||
struct hci_conn_params *params;
|
struct hci_conn_params *params;
|
||||||
struct hci_conn *conn;
|
struct hci_conn *conn;
|
||||||
struct smp_irk *irk;
|
struct smp_irk *irk;
|
||||||
u8 addr_type;
|
u8 addr_type;
|
||||||
|
|
||||||
BT_DBG("%s status 0x%2.2x", hdev->name, ev->status);
|
|
||||||
|
|
||||||
hci_dev_lock(hdev);
|
hci_dev_lock(hdev);
|
||||||
|
|
||||||
/* All controllers implicitly stop advertising in the event of a
|
/* All controllers implicitly stop advertising in the event of a
|
||||||
@@ -4570,13 +4577,13 @@ static void hci_le_conn_complete_evt(struct hci_dev *hdev, struct sk_buff *skb)
|
|||||||
|
|
||||||
conn = hci_lookup_le_connect(hdev);
|
conn = hci_lookup_le_connect(hdev);
|
||||||
if (!conn) {
|
if (!conn) {
|
||||||
conn = hci_conn_add(hdev, LE_LINK, &ev->bdaddr, ev->role);
|
conn = hci_conn_add(hdev, LE_LINK, bdaddr, role);
|
||||||
if (!conn) {
|
if (!conn) {
|
||||||
bt_dev_err(hdev, "no memory for new connection");
|
bt_dev_err(hdev, "no memory for new connection");
|
||||||
goto unlock;
|
goto unlock;
|
||||||
}
|
}
|
||||||
|
|
||||||
conn->dst_type = ev->bdaddr_type;
|
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 master role this must be something
|
* but we're in master role this must be something
|
||||||
@@ -4587,8 +4594,8 @@ static void hci_le_conn_complete_evt(struct hci_dev *hdev, struct sk_buff *skb)
|
|||||||
* initiator address based on the HCI_PRIVACY flag.
|
* initiator address based on the HCI_PRIVACY flag.
|
||||||
*/
|
*/
|
||||||
if (conn->out) {
|
if (conn->out) {
|
||||||
conn->resp_addr_type = ev->bdaddr_type;
|
conn->resp_addr_type = bdaddr_type;
|
||||||
bacpy(&conn->resp_addr, &ev->bdaddr);
|
bacpy(&conn->resp_addr, bdaddr);
|
||||||
if (hci_dev_test_flag(hdev, HCI_PRIVACY)) {
|
if (hci_dev_test_flag(hdev, HCI_PRIVACY)) {
|
||||||
conn->init_addr_type = ADDR_LE_DEV_RANDOM;
|
conn->init_addr_type = ADDR_LE_DEV_RANDOM;
|
||||||
bacpy(&conn->init_addr, &hdev->rpa);
|
bacpy(&conn->init_addr, &hdev->rpa);
|
||||||
@@ -4612,8 +4619,8 @@ static void hci_le_conn_complete_evt(struct hci_dev *hdev, struct sk_buff *skb)
|
|||||||
else
|
else
|
||||||
bacpy(&conn->resp_addr, &hdev->bdaddr);
|
bacpy(&conn->resp_addr, &hdev->bdaddr);
|
||||||
|
|
||||||
conn->init_addr_type = ev->bdaddr_type;
|
conn->init_addr_type = bdaddr_type;
|
||||||
bacpy(&conn->init_addr, &ev->bdaddr);
|
bacpy(&conn->init_addr, bdaddr);
|
||||||
|
|
||||||
/* For incoming connections, set the default minimum
|
/* For incoming connections, set the default minimum
|
||||||
* and maximum connection interval. They will be used
|
* and maximum connection interval. They will be used
|
||||||
@@ -4639,8 +4646,8 @@ static void hci_le_conn_complete_evt(struct hci_dev *hdev, struct sk_buff *skb)
|
|||||||
conn->dst_type = irk->addr_type;
|
conn->dst_type = irk->addr_type;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (ev->status) {
|
if (status) {
|
||||||
hci_le_conn_failed(conn, ev->status);
|
hci_le_conn_failed(conn, status);
|
||||||
goto unlock;
|
goto unlock;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -4659,17 +4666,17 @@ static void hci_le_conn_complete_evt(struct hci_dev *hdev, struct sk_buff *skb)
|
|||||||
mgmt_device_connected(hdev, conn, 0, NULL, 0);
|
mgmt_device_connected(hdev, conn, 0, NULL, 0);
|
||||||
|
|
||||||
conn->sec_level = BT_SECURITY_LOW;
|
conn->sec_level = BT_SECURITY_LOW;
|
||||||
conn->handle = __le16_to_cpu(ev->handle);
|
conn->handle = handle;
|
||||||
conn->state = BT_CONFIG;
|
conn->state = BT_CONFIG;
|
||||||
|
|
||||||
conn->le_conn_interval = le16_to_cpu(ev->interval);
|
conn->le_conn_interval = interval;
|
||||||
conn->le_conn_latency = le16_to_cpu(ev->latency);
|
conn->le_conn_latency = latency;
|
||||||
conn->le_supv_timeout = le16_to_cpu(ev->supervision_timeout);
|
conn->le_supv_timeout = supervision_timeout;
|
||||||
|
|
||||||
hci_debugfs_create_conn(conn);
|
hci_debugfs_create_conn(conn);
|
||||||
hci_conn_add_sysfs(conn);
|
hci_conn_add_sysfs(conn);
|
||||||
|
|
||||||
if (!ev->status) {
|
if (!status) {
|
||||||
/* The remote features procedure is defined for master
|
/* The remote features procedure is defined for master
|
||||||
* role only. So only in case of an initiated connection
|
* role only. So only in case of an initiated connection
|
||||||
* request the remote features.
|
* request the remote features.
|
||||||
@@ -4691,10 +4698,10 @@ static void hci_le_conn_complete_evt(struct hci_dev *hdev, struct sk_buff *skb)
|
|||||||
hci_conn_hold(conn);
|
hci_conn_hold(conn);
|
||||||
} else {
|
} else {
|
||||||
conn->state = BT_CONNECTED;
|
conn->state = BT_CONNECTED;
|
||||||
hci_connect_cfm(conn, ev->status);
|
hci_connect_cfm(conn, status);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
hci_connect_cfm(conn, ev->status);
|
hci_connect_cfm(conn, status);
|
||||||
}
|
}
|
||||||
|
|
||||||
params = hci_pend_le_action_lookup(&hdev->pend_le_conns, &conn->dst,
|
params = hci_pend_le_action_lookup(&hdev->pend_le_conns, &conn->dst,
|
||||||
@@ -4713,6 +4720,19 @@ unlock:
|
|||||||
hci_dev_unlock(hdev);
|
hci_dev_unlock(hdev);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void hci_le_conn_complete_evt(struct hci_dev *hdev, struct sk_buff *skb)
|
||||||
|
{
|
||||||
|
struct hci_ev_le_conn_complete *ev = (void *) skb->data;
|
||||||
|
|
||||||
|
BT_DBG("%s status 0x%2.2x", hdev->name, ev->status);
|
||||||
|
|
||||||
|
le_conn_complete_evt(hdev, ev->status, &ev->bdaddr, ev->bdaddr_type,
|
||||||
|
ev->role, le16_to_cpu(ev->handle),
|
||||||
|
le16_to_cpu(ev->interval),
|
||||||
|
le16_to_cpu(ev->latency),
|
||||||
|
le16_to_cpu(ev->supervision_timeout));
|
||||||
|
}
|
||||||
|
|
||||||
static void hci_le_conn_update_complete_evt(struct hci_dev *hdev,
|
static void hci_le_conn_update_complete_evt(struct hci_dev *hdev,
|
||||||
struct sk_buff *skb)
|
struct sk_buff *skb)
|
||||||
{
|
{
|
||||||
|
|||||||
Reference in New Issue
Block a user