Commit d12fb056 authored by Jaganath Kanakkassery's avatar Jaganath Kanakkassery Committed by Marcel Holtmann

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: default avatarJaganath Kanakkassery <jaganathx.kanakkassery@intel.com>
Signed-off-by: default avatarMarcel Holtmann <marcel@holtmann.org>
parent c215e939
...@@ -1971,55 +1971,63 @@ static void hci_cs_disconnect(struct hci_dev *hdev, u8 status) ...@@ -1971,55 +1971,63 @@ static void hci_cs_disconnect(struct hci_dev *hdev, u8 status)
hci_dev_unlock(hdev); hci_dev_unlock(hdev);
} }
static void hci_cs_le_create_conn(struct hci_dev *hdev, u8 status) 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_cp_le_create_conn *cp;
struct hci_conn *conn; struct hci_conn *conn;
BT_DBG("%s status 0x%2.2x", hdev->name, status); conn = hci_conn_hash_lookup_le(hdev, peer_addr,
peer_addr_type);
/* All connection failure handling is taken care of by the
* hci_le_conn_failed function which is triggered by the HCI
* request completion callbacks used for connecting.
*/
if (status)
return;
cp = hci_sent_cmd_data(hdev, HCI_OP_LE_CREATE_CONN);
if (!cp)
return;
hci_dev_lock(hdev);
conn = hci_conn_hash_lookup_le(hdev, &cp->peer_addr,
cp->peer_addr_type);
if (!conn) if (!conn)
goto unlock; return;
/* Store the initiator and responder address information which /* Store the initiator and responder address information which
* is needed for SMP. These values will not change during the * is needed for SMP. These values will not change during the
* lifetime of the connection. * lifetime of the connection.
*/ */
conn->init_addr_type = cp->own_address_type; conn->init_addr_type = own_address_type;
if (cp->own_address_type == ADDR_LE_DEV_RANDOM) if (own_address_type == ADDR_LE_DEV_RANDOM)
bacpy(&conn->init_addr, &hdev->random_addr); bacpy(&conn->init_addr, &hdev->random_addr);
else else
bacpy(&conn->init_addr, &hdev->bdaddr); bacpy(&conn->init_addr, &hdev->bdaddr);
conn->resp_addr_type = cp->peer_addr_type; conn->resp_addr_type = peer_addr_type;
bacpy(&conn->resp_addr, &cp->peer_addr); bacpy(&conn->resp_addr, peer_addr);
/* We don't want the connection attempt to stick around /* We don't want the connection attempt to stick around
* indefinitely since LE doesn't have a page timeout concept * indefinitely since LE doesn't have a page timeout concept
* like BR/EDR. Set a timer for any connection that doesn't use * like BR/EDR. Set a timer for any connection that doesn't use
* the white list for connecting. * the white list for connecting.
*/ */
if (cp->filter_policy == HCI_LE_USE_PEER_ADDR) if (filter_policy == HCI_LE_USE_PEER_ADDR)
queue_delayed_work(conn->hdev->workqueue, queue_delayed_work(conn->hdev->workqueue,
&conn->le_conn_timeout, &conn->le_conn_timeout,
conn->conn_timeout); conn->conn_timeout);
}
static void hci_cs_le_create_conn(struct hci_dev *hdev, u8 status)
{
struct hci_cp_le_create_conn *cp;
BT_DBG("%s status 0x%2.2x", hdev->name, status);
/* All connection failure handling is taken care of by the
* hci_le_conn_failed function which is triggered by the HCI
* request completion callbacks used for connecting.
*/
if (status)
return;
cp = hci_sent_cmd_data(hdev, HCI_OP_LE_CREATE_CONN);
if (!cp)
return;
hci_dev_lock(hdev);
cs_le_create_conn(hdev, &cp->peer_addr, cp->peer_addr_type,
cp->own_address_type, cp->filter_policy);
unlock:
hci_dev_unlock(hdev); hci_dev_unlock(hdev);
} }
...@@ -4551,16 +4559,15 @@ static void hci_disconn_phylink_complete_evt(struct hci_dev *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) ...@@ -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) ...@@ -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) ...@@ -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) ...@@ -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) ...@@ -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) ...@@ -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 @@ static void hci_le_conn_complete_evt(struct hci_dev *hdev, struct sk_buff *skb) ...@@ -4713,6 +4720,19 @@ static void hci_le_conn_complete_evt(struct hci_dev *hdev, struct sk_buff *skb)
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)
{ {
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment