Merge branch 'for-upstream' of git://git.kernel.org/pub/scm/linux/kernel/git/bluetooth/bluetooth-next
Johan Hedberg says: ==================== pull request: bluetooth-next 2015-08-16 Here's what's likely the last bluetooth-next pull request for 4.3: - 6lowpan/802.15.4 refactoring, cleanups & fixes - Document 6lowpan netdev usage in Documentation/networking/6lowpan.txt - Support for UART based QCA Bluetooth controllers - Power management support for Broeadcom Bluetooth controllers - Change LE connection initiation to always use passive scanning first - Support for new Silicon Wave USB ID Please let me know if there are any issues pulling. Thanks. ==================== Signed-off-by: David S. Miller <davem@davemloft.net>
This commit is contained in:
@@ -85,7 +85,7 @@ struct lowpan_dev {
|
||||
|
||||
static inline struct lowpan_dev *lowpan_dev(const struct net_device *netdev)
|
||||
{
|
||||
return netdev_priv(netdev);
|
||||
return (struct lowpan_dev *)lowpan_priv(netdev)->priv;
|
||||
}
|
||||
|
||||
static inline void peer_add(struct lowpan_dev *dev, struct lowpan_peer *peer)
|
||||
@@ -848,8 +848,9 @@ static int setup_netdev(struct l2cap_chan *chan, struct lowpan_dev **dev)
|
||||
struct net_device *netdev;
|
||||
int err = 0;
|
||||
|
||||
netdev = alloc_netdev(sizeof(struct lowpan_dev), IFACE_NAME_TEMPLATE,
|
||||
NET_NAME_UNKNOWN, netdev_setup);
|
||||
netdev = alloc_netdev(LOWPAN_PRIV_SIZE(sizeof(struct lowpan_dev)),
|
||||
IFACE_NAME_TEMPLATE, NET_NAME_UNKNOWN,
|
||||
netdev_setup);
|
||||
if (!netdev)
|
||||
return -ENOMEM;
|
||||
|
||||
@@ -859,7 +860,7 @@ static int setup_netdev(struct l2cap_chan *chan, struct lowpan_dev **dev)
|
||||
SET_NETDEV_DEV(netdev, &chan->conn->hcon->hdev->dev);
|
||||
SET_NETDEV_DEVTYPE(netdev, &bt_type);
|
||||
|
||||
*dev = netdev_priv(netdev);
|
||||
*dev = lowpan_dev(netdev);
|
||||
(*dev)->netdev = netdev;
|
||||
(*dev)->hdev = chan->conn->hcon->hdev;
|
||||
INIT_LIST_HEAD(&(*dev)->peers);
|
||||
@@ -869,6 +870,8 @@ static int setup_netdev(struct l2cap_chan *chan, struct lowpan_dev **dev)
|
||||
list_add_rcu(&(*dev)->list, &bt_6lowpan_devices);
|
||||
spin_unlock(&devices_lock);
|
||||
|
||||
lowpan_netdev_setup(netdev, LOWPAN_LLTYPE_BTLE);
|
||||
|
||||
err = register_netdev(netdev);
|
||||
if (err < 0) {
|
||||
BT_INFO("register_netdev failed %d", err);
|
||||
|
@@ -379,7 +379,7 @@ static bool amp_write_rem_assoc_frag(struct hci_dev *hdev,
|
||||
amp_ctrl_put(ctrl);
|
||||
|
||||
hci_req_init(&req, hdev);
|
||||
hci_req_add(&req, HCI_OP_WRITE_REMOTE_AMP_ASSOC, sizeof(cp), &cp);
|
||||
hci_req_add(&req, HCI_OP_WRITE_REMOTE_AMP_ASSOC, len, cp);
|
||||
hci_req_run_skb(&req, write_remote_amp_assoc_complete);
|
||||
|
||||
kfree(cp);
|
||||
|
@@ -64,6 +64,48 @@ static void hci_le_create_connection_cancel(struct hci_conn *conn)
|
||||
hci_send_cmd(conn->hdev, HCI_OP_LE_CREATE_CONN_CANCEL, 0, NULL);
|
||||
}
|
||||
|
||||
/* This function requires the caller holds hdev->lock */
|
||||
static void hci_connect_le_scan_cleanup(struct hci_conn *conn)
|
||||
{
|
||||
struct hci_conn_params *params;
|
||||
struct smp_irk *irk;
|
||||
bdaddr_t *bdaddr;
|
||||
u8 bdaddr_type;
|
||||
|
||||
bdaddr = &conn->dst;
|
||||
bdaddr_type = conn->dst_type;
|
||||
|
||||
/* Check if we need to convert to identity address */
|
||||
irk = hci_get_irk(conn->hdev, bdaddr, bdaddr_type);
|
||||
if (irk) {
|
||||
bdaddr = &irk->bdaddr;
|
||||
bdaddr_type = irk->addr_type;
|
||||
}
|
||||
|
||||
params = hci_explicit_connect_lookup(conn->hdev, bdaddr, bdaddr_type);
|
||||
if (!params)
|
||||
return;
|
||||
|
||||
/* The connection attempt was doing scan for new RPA, and is
|
||||
* in scan phase. If params are not associated with any other
|
||||
* autoconnect action, remove them completely. If they are, just unmark
|
||||
* them as waiting for connection, by clearing explicit_connect field.
|
||||
*/
|
||||
if (params->auto_connect == HCI_AUTO_CONN_EXPLICIT)
|
||||
hci_conn_params_del(conn->hdev, bdaddr, bdaddr_type);
|
||||
else
|
||||
params->explicit_connect = false;
|
||||
}
|
||||
|
||||
/* This function requires the caller holds hdev->lock */
|
||||
static void hci_connect_le_scan_remove(struct hci_conn *conn)
|
||||
{
|
||||
hci_connect_le_scan_cleanup(conn);
|
||||
|
||||
hci_conn_hash_del(conn->hdev, conn);
|
||||
hci_update_background_scan(conn->hdev);
|
||||
}
|
||||
|
||||
static void hci_acl_create_connection(struct hci_conn *conn)
|
||||
{
|
||||
struct hci_dev *hdev = conn->hdev;
|
||||
@@ -340,8 +382,12 @@ static void hci_conn_timeout(struct work_struct *work)
|
||||
if (conn->out) {
|
||||
if (conn->type == ACL_LINK)
|
||||
hci_acl_create_connection_cancel(conn);
|
||||
else if (conn->type == LE_LINK)
|
||||
hci_le_create_connection_cancel(conn);
|
||||
else if (conn->type == LE_LINK) {
|
||||
if (test_bit(HCI_CONN_SCANNING, &conn->flags))
|
||||
hci_connect_le_scan_remove(conn);
|
||||
else
|
||||
hci_le_create_connection_cancel(conn);
|
||||
}
|
||||
} else if (conn->type == SCO_LINK || conn->type == ESCO_LINK) {
|
||||
hci_reject_sco(conn);
|
||||
}
|
||||
@@ -637,15 +683,18 @@ static void create_le_conn_complete(struct hci_dev *hdev, u8 status, u16 opcode)
|
||||
{
|
||||
struct hci_conn *conn;
|
||||
|
||||
if (status == 0)
|
||||
return;
|
||||
hci_dev_lock(hdev);
|
||||
|
||||
conn = hci_lookup_le_connect(hdev);
|
||||
|
||||
if (!status) {
|
||||
hci_connect_le_scan_cleanup(conn);
|
||||
goto done;
|
||||
}
|
||||
|
||||
BT_ERR("HCI request failed to create LE connection: status 0x%2.2x",
|
||||
status);
|
||||
|
||||
hci_dev_lock(hdev);
|
||||
|
||||
conn = hci_conn_hash_lookup_state(hdev, LE_LINK, BT_CONNECT);
|
||||
if (!conn)
|
||||
goto done;
|
||||
|
||||
@@ -685,6 +734,7 @@ static void hci_req_add_le_create_conn(struct hci_request *req,
|
||||
hci_req_add(req, HCI_OP_LE_CREATE_CONN, sizeof(cp), &cp);
|
||||
|
||||
conn->state = BT_CONNECT;
|
||||
clear_bit(HCI_CONN_SCANNING, &conn->flags);
|
||||
}
|
||||
|
||||
static void hci_req_directed_advertising(struct hci_request *req,
|
||||
@@ -728,7 +778,7 @@ struct hci_conn *hci_connect_le(struct hci_dev *hdev, bdaddr_t *dst,
|
||||
u8 role)
|
||||
{
|
||||
struct hci_conn_params *params;
|
||||
struct hci_conn *conn;
|
||||
struct hci_conn *conn, *conn_unfinished;
|
||||
struct smp_irk *irk;
|
||||
struct hci_request req;
|
||||
int err;
|
||||
@@ -751,26 +801,29 @@ struct hci_conn *hci_connect_le(struct hci_dev *hdev, bdaddr_t *dst,
|
||||
* and return the object found.
|
||||
*/
|
||||
conn = hci_conn_hash_lookup_ba(hdev, LE_LINK, dst);
|
||||
conn_unfinished = NULL;
|
||||
if (conn) {
|
||||
conn->pending_sec_level = sec_level;
|
||||
goto done;
|
||||
if (conn->state == BT_CONNECT &&
|
||||
test_bit(HCI_CONN_SCANNING, &conn->flags)) {
|
||||
BT_DBG("will continue unfinished conn %pMR", dst);
|
||||
conn_unfinished = conn;
|
||||
} else {
|
||||
if (conn->pending_sec_level < sec_level)
|
||||
conn->pending_sec_level = sec_level;
|
||||
goto done;
|
||||
}
|
||||
}
|
||||
|
||||
/* Since the controller supports only one LE connection attempt at a
|
||||
* time, we return -EBUSY if there is any connection attempt running.
|
||||
*/
|
||||
conn = hci_conn_hash_lookup_state(hdev, LE_LINK, BT_CONNECT);
|
||||
if (conn)
|
||||
if (hci_lookup_le_connect(hdev))
|
||||
return ERR_PTR(-EBUSY);
|
||||
|
||||
/* When given an identity address with existing identity
|
||||
* resolving key, the connection needs to be established
|
||||
* to a resolvable random address.
|
||||
*
|
||||
* This uses the cached random resolvable address from
|
||||
* a previous scan. When no cached address is available,
|
||||
* try connecting to the identity address instead.
|
||||
*
|
||||
* Storing the resolvable random address is required here
|
||||
* to handle connection failures. The address will later
|
||||
* be resolved back into the original identity address
|
||||
@@ -782,15 +835,23 @@ struct hci_conn *hci_connect_le(struct hci_dev *hdev, bdaddr_t *dst,
|
||||
dst_type = ADDR_LE_DEV_RANDOM;
|
||||
}
|
||||
|
||||
conn = hci_conn_add(hdev, LE_LINK, dst, role);
|
||||
if (conn_unfinished) {
|
||||
conn = conn_unfinished;
|
||||
bacpy(&conn->dst, dst);
|
||||
} else {
|
||||
conn = hci_conn_add(hdev, LE_LINK, dst, role);
|
||||
}
|
||||
|
||||
if (!conn)
|
||||
return ERR_PTR(-ENOMEM);
|
||||
|
||||
conn->dst_type = dst_type;
|
||||
conn->sec_level = BT_SECURITY_LOW;
|
||||
conn->pending_sec_level = sec_level;
|
||||
conn->conn_timeout = conn_timeout;
|
||||
|
||||
if (!conn_unfinished)
|
||||
conn->pending_sec_level = sec_level;
|
||||
|
||||
hci_req_init(&req, hdev);
|
||||
|
||||
/* Disable advertising if we're active. For master role
|
||||
@@ -854,6 +915,144 @@ create_conn:
|
||||
return ERR_PTR(err);
|
||||
}
|
||||
|
||||
done:
|
||||
/* If this is continuation of connect started by hci_connect_le_scan,
|
||||
* it already called hci_conn_hold and calling it again would mess the
|
||||
* counter.
|
||||
*/
|
||||
if (!conn_unfinished)
|
||||
hci_conn_hold(conn);
|
||||
|
||||
return conn;
|
||||
}
|
||||
|
||||
static void hci_connect_le_scan_complete(struct hci_dev *hdev, u8 status,
|
||||
u16 opcode)
|
||||
{
|
||||
struct hci_conn *conn;
|
||||
|
||||
if (!status)
|
||||
return;
|
||||
|
||||
BT_ERR("Failed to add device to auto conn whitelist: status 0x%2.2x",
|
||||
status);
|
||||
|
||||
hci_dev_lock(hdev);
|
||||
|
||||
conn = hci_conn_hash_lookup_state(hdev, LE_LINK, BT_CONNECT);
|
||||
if (conn)
|
||||
hci_le_conn_failed(conn, status);
|
||||
|
||||
hci_dev_unlock(hdev);
|
||||
}
|
||||
|
||||
static bool is_connected(struct hci_dev *hdev, bdaddr_t *addr, u8 type)
|
||||
{
|
||||
struct hci_conn *conn;
|
||||
|
||||
conn = hci_conn_hash_lookup_ba(hdev, LE_LINK, addr);
|
||||
if (!conn)
|
||||
return false;
|
||||
|
||||
if (conn->dst_type != type)
|
||||
return false;
|
||||
|
||||
if (conn->state != BT_CONNECTED)
|
||||
return false;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/* This function requires the caller holds hdev->lock */
|
||||
static int hci_explicit_conn_params_set(struct hci_request *req,
|
||||
bdaddr_t *addr, u8 addr_type)
|
||||
{
|
||||
struct hci_dev *hdev = req->hdev;
|
||||
struct hci_conn_params *params;
|
||||
|
||||
if (is_connected(hdev, addr, addr_type))
|
||||
return -EISCONN;
|
||||
|
||||
params = hci_conn_params_add(hdev, addr, addr_type);
|
||||
if (!params)
|
||||
return -EIO;
|
||||
|
||||
/* If we created new params, or existing params were marked as disabled,
|
||||
* mark them to be used just once to connect.
|
||||
*/
|
||||
if (params->auto_connect == HCI_AUTO_CONN_DISABLED) {
|
||||
params->auto_connect = HCI_AUTO_CONN_EXPLICIT;
|
||||
list_del_init(¶ms->action);
|
||||
list_add(¶ms->action, &hdev->pend_le_conns);
|
||||
}
|
||||
|
||||
params->explicit_connect = true;
|
||||
__hci_update_background_scan(req);
|
||||
|
||||
BT_DBG("addr %pMR (type %u) auto_connect %u", addr, addr_type,
|
||||
params->auto_connect);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* This function requires the caller holds hdev->lock */
|
||||
struct hci_conn *hci_connect_le_scan(struct hci_dev *hdev, bdaddr_t *dst,
|
||||
u8 dst_type, u8 sec_level,
|
||||
u16 conn_timeout, u8 role)
|
||||
{
|
||||
struct hci_conn *conn;
|
||||
struct hci_request req;
|
||||
int err;
|
||||
|
||||
/* Let's make sure that le is enabled.*/
|
||||
if (!hci_dev_test_flag(hdev, HCI_LE_ENABLED)) {
|
||||
if (lmp_le_capable(hdev))
|
||||
return ERR_PTR(-ECONNREFUSED);
|
||||
|
||||
return ERR_PTR(-EOPNOTSUPP);
|
||||
}
|
||||
|
||||
/* Some devices send ATT messages as soon as the physical link is
|
||||
* established. To be able to handle these ATT messages, the user-
|
||||
* space first establishes the connection and then starts the pairing
|
||||
* process.
|
||||
*
|
||||
* So if a hci_conn object already exists for the following connection
|
||||
* attempt, we simply update pending_sec_level and auth_type fields
|
||||
* and return the object found.
|
||||
*/
|
||||
conn = hci_conn_hash_lookup_ba(hdev, LE_LINK, dst);
|
||||
if (conn) {
|
||||
if (conn->pending_sec_level < sec_level)
|
||||
conn->pending_sec_level = sec_level;
|
||||
goto done;
|
||||
}
|
||||
|
||||
BT_DBG("requesting refresh of dst_addr");
|
||||
|
||||
conn = hci_conn_add(hdev, LE_LINK, dst, role);
|
||||
if (!conn)
|
||||
return ERR_PTR(-ENOMEM);
|
||||
|
||||
hci_req_init(&req, hdev);
|
||||
|
||||
if (hci_explicit_conn_params_set(&req, dst, dst_type) < 0)
|
||||
return ERR_PTR(-EBUSY);
|
||||
|
||||
conn->state = BT_CONNECT;
|
||||
set_bit(HCI_CONN_SCANNING, &conn->flags);
|
||||
|
||||
err = hci_req_run(&req, hci_connect_le_scan_complete);
|
||||
if (err && err != -ENODATA) {
|
||||
hci_conn_del(conn);
|
||||
return ERR_PTR(err);
|
||||
}
|
||||
|
||||
conn->dst_type = dst_type;
|
||||
conn->sec_level = BT_SECURITY_LOW;
|
||||
conn->pending_sec_level = sec_level;
|
||||
conn->conn_timeout = conn_timeout;
|
||||
|
||||
done:
|
||||
hci_conn_hold(conn);
|
||||
return conn;
|
||||
|
@@ -2847,6 +2847,30 @@ struct hci_conn_params *hci_pend_le_action_lookup(struct list_head *list,
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/* This function requires the caller holds hdev->lock */
|
||||
struct hci_conn_params *hci_explicit_connect_lookup(struct hci_dev *hdev,
|
||||
bdaddr_t *addr,
|
||||
u8 addr_type)
|
||||
{
|
||||
struct hci_conn_params *param;
|
||||
|
||||
list_for_each_entry(param, &hdev->pend_le_conns, action) {
|
||||
if (bacmp(¶m->addr, addr) == 0 &&
|
||||
param->addr_type == addr_type &&
|
||||
param->explicit_connect)
|
||||
return param;
|
||||
}
|
||||
|
||||
list_for_each_entry(param, &hdev->pend_le_reports, action) {
|
||||
if (bacmp(¶m->addr, addr) == 0 &&
|
||||
param->addr_type == addr_type &&
|
||||
param->explicit_connect)
|
||||
return param;
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/* This function requires the caller holds hdev->lock */
|
||||
struct hci_conn_params *hci_conn_params_add(struct hci_dev *hdev,
|
||||
bdaddr_t *addr, u8 addr_type)
|
||||
@@ -2916,6 +2940,15 @@ void hci_conn_params_clear_disabled(struct hci_dev *hdev)
|
||||
list_for_each_entry_safe(params, tmp, &hdev->le_conn_params, list) {
|
||||
if (params->auto_connect != HCI_AUTO_CONN_DISABLED)
|
||||
continue;
|
||||
|
||||
/* If trying to estabilish one time connection to disabled
|
||||
* device, leave the params, but mark them as just once.
|
||||
*/
|
||||
if (params->explicit_connect) {
|
||||
params->auto_connect = HCI_AUTO_CONN_EXPLICIT;
|
||||
continue;
|
||||
}
|
||||
|
||||
list_del(¶ms->list);
|
||||
kfree(params);
|
||||
}
|
||||
|
@@ -1059,7 +1059,7 @@ static void hci_cc_le_set_adv_enable(struct hci_dev *hdev, struct sk_buff *skb)
|
||||
|
||||
hci_dev_set_flag(hdev, HCI_LE_ADV);
|
||||
|
||||
conn = hci_conn_hash_lookup_state(hdev, LE_LINK, BT_CONNECT);
|
||||
conn = hci_lookup_le_connect(hdev);
|
||||
if (conn)
|
||||
queue_delayed_work(hdev->workqueue,
|
||||
&conn->le_conn_timeout,
|
||||
@@ -4447,7 +4447,7 @@ static void hci_le_conn_complete_evt(struct hci_dev *hdev, struct sk_buff *skb)
|
||||
*/
|
||||
hci_dev_clear_flag(hdev, HCI_LE_ADV);
|
||||
|
||||
conn = hci_conn_hash_lookup_state(hdev, LE_LINK, BT_CONNECT);
|
||||
conn = hci_lookup_le_connect(hdev);
|
||||
if (!conn) {
|
||||
conn = hci_conn_add(hdev, LE_LINK, &ev->bdaddr, ev->role);
|
||||
if (!conn) {
|
||||
@@ -4640,42 +4640,49 @@ static struct hci_conn *check_pending_le_conn(struct hci_dev *hdev,
|
||||
/* If we're not connectable only connect devices that we have in
|
||||
* our pend_le_conns list.
|
||||
*/
|
||||
params = hci_pend_le_action_lookup(&hdev->pend_le_conns,
|
||||
addr, addr_type);
|
||||
params = hci_explicit_connect_lookup(hdev, addr, addr_type);
|
||||
|
||||
if (!params)
|
||||
return NULL;
|
||||
|
||||
switch (params->auto_connect) {
|
||||
case HCI_AUTO_CONN_DIRECT:
|
||||
/* Only devices advertising with ADV_DIRECT_IND are
|
||||
* triggering a connection attempt. This is allowing
|
||||
* incoming connections from slave devices.
|
||||
*/
|
||||
if (adv_type != LE_ADV_DIRECT_IND)
|
||||
if (!params->explicit_connect) {
|
||||
switch (params->auto_connect) {
|
||||
case HCI_AUTO_CONN_DIRECT:
|
||||
/* Only devices advertising with ADV_DIRECT_IND are
|
||||
* triggering a connection attempt. This is allowing
|
||||
* incoming connections from slave devices.
|
||||
*/
|
||||
if (adv_type != LE_ADV_DIRECT_IND)
|
||||
return NULL;
|
||||
break;
|
||||
case HCI_AUTO_CONN_ALWAYS:
|
||||
/* Devices advertising with ADV_IND or ADV_DIRECT_IND
|
||||
* are triggering a connection attempt. This means
|
||||
* that incoming connectioms from slave device are
|
||||
* accepted and also outgoing connections to slave
|
||||
* devices are established when found.
|
||||
*/
|
||||
break;
|
||||
default:
|
||||
return NULL;
|
||||
break;
|
||||
case HCI_AUTO_CONN_ALWAYS:
|
||||
/* Devices advertising with ADV_IND or ADV_DIRECT_IND
|
||||
* are triggering a connection attempt. This means
|
||||
* that incoming connectioms from slave device are
|
||||
* accepted and also outgoing connections to slave
|
||||
* devices are established when found.
|
||||
*/
|
||||
break;
|
||||
default:
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
|
||||
conn = hci_connect_le(hdev, addr, addr_type, BT_SECURITY_LOW,
|
||||
HCI_LE_AUTOCONN_TIMEOUT, HCI_ROLE_MASTER);
|
||||
if (!IS_ERR(conn)) {
|
||||
/* Store the pointer since we don't really have any
|
||||
/* If HCI_AUTO_CONN_EXPLICIT is set, conn is already owned
|
||||
* by higher layer that tried to connect, if no then
|
||||
* store the pointer since we don't really have any
|
||||
* other owner of the object besides the params that
|
||||
* triggered it. This way we can abort the connection if
|
||||
* the parameters get removed and keep the reference
|
||||
* count consistent once the connection is established.
|
||||
*/
|
||||
params->conn = hci_conn_get(conn);
|
||||
|
||||
if (!params->explicit_connect)
|
||||
params->conn = hci_conn_get(conn);
|
||||
|
||||
return conn;
|
||||
}
|
||||
|
||||
|
@@ -317,7 +317,7 @@ static void set_random_addr(struct hci_request *req, bdaddr_t *rpa)
|
||||
* address be updated at the next cycle.
|
||||
*/
|
||||
if (hci_dev_test_flag(hdev, HCI_LE_ADV) ||
|
||||
hci_conn_hash_lookup_state(hdev, LE_LINK, BT_CONNECT)) {
|
||||
hci_lookup_le_connect(hdev)) {
|
||||
BT_DBG("Deferring random address update");
|
||||
hci_dev_set_flag(hdev, HCI_RPA_EXPIRED);
|
||||
return;
|
||||
@@ -479,7 +479,6 @@ void hci_update_page_scan(struct hci_dev *hdev)
|
||||
void __hci_update_background_scan(struct hci_request *req)
|
||||
{
|
||||
struct hci_dev *hdev = req->hdev;
|
||||
struct hci_conn *conn;
|
||||
|
||||
if (!test_bit(HCI_UP, &hdev->flags) ||
|
||||
test_bit(HCI_INIT, &hdev->flags) ||
|
||||
@@ -529,8 +528,7 @@ void __hci_update_background_scan(struct hci_request *req)
|
||||
* since some controllers are not able to scan and connect at
|
||||
* the same time.
|
||||
*/
|
||||
conn = hci_conn_hash_lookup_state(hdev, LE_LINK, BT_CONNECT);
|
||||
if (conn)
|
||||
if (hci_lookup_le_connect(hdev))
|
||||
return;
|
||||
|
||||
/* If controller is currently scanning, we stop it to ensure we
|
||||
|
@@ -7113,8 +7113,10 @@ int l2cap_chan_connect(struct l2cap_chan *chan, __le16 psm, u16 cid,
|
||||
else
|
||||
role = HCI_ROLE_MASTER;
|
||||
|
||||
hcon = hci_connect_le(hdev, dst, dst_type, chan->sec_level,
|
||||
HCI_LE_CONN_TIMEOUT, role);
|
||||
hcon = hci_connect_le_scan(hdev, dst, dst_type,
|
||||
chan->sec_level,
|
||||
HCI_LE_CONN_TIMEOUT,
|
||||
role);
|
||||
} else {
|
||||
u8 auth_type = l2cap_get_auth_type(chan);
|
||||
hcon = hci_connect_acl(hdev, dst, chan->sec_level, auth_type);
|
||||
|
@@ -3564,9 +3564,10 @@ static int pair_device(struct sock *sk, struct hci_dev *hdev, void *data,
|
||||
*/
|
||||
hci_conn_params_add(hdev, &cp->addr.bdaddr, addr_type);
|
||||
|
||||
conn = hci_connect_le(hdev, &cp->addr.bdaddr, addr_type,
|
||||
sec_level, HCI_LE_CONN_TIMEOUT,
|
||||
HCI_ROLE_MASTER);
|
||||
conn = hci_connect_le_scan(hdev, &cp->addr.bdaddr,
|
||||
addr_type, sec_level,
|
||||
HCI_LE_CONN_TIMEOUT,
|
||||
HCI_ROLE_MASTER);
|
||||
}
|
||||
|
||||
if (IS_ERR(conn)) {
|
||||
@@ -4210,7 +4211,7 @@ static bool trigger_le_scan(struct hci_request *req, u16 interval, u8 *status)
|
||||
/* Don't let discovery abort an outgoing connection attempt
|
||||
* that's using directed advertising.
|
||||
*/
|
||||
if (hci_conn_hash_lookup_state(hdev, LE_LINK, BT_CONNECT)) {
|
||||
if (hci_lookup_le_connect(hdev)) {
|
||||
*status = MGMT_STATUS_REJECTED;
|
||||
return false;
|
||||
}
|
||||
@@ -6107,6 +6108,12 @@ static int hci_conn_params_set(struct hci_request *req, bdaddr_t *addr,
|
||||
switch (auto_connect) {
|
||||
case HCI_AUTO_CONN_DISABLED:
|
||||
case HCI_AUTO_CONN_LINK_LOSS:
|
||||
/* If auto connect is being disabled when we're trying to
|
||||
* connect to device, keep connecting.
|
||||
*/
|
||||
if (params->explicit_connect)
|
||||
list_add(¶ms->action, &hdev->pend_le_conns);
|
||||
|
||||
__hci_update_background_scan(req);
|
||||
break;
|
||||
case HCI_AUTO_CONN_REPORT:
|
||||
|
Reference in New Issue
Block a user