/* BlueZ - Bluetooth protocol stack for Linux Copyright (c) 2000-2001, 2010, Code Aurora Forum. All rights reserved. Copyright 2023-2024 NXP
Written 2000,2001 by Maxim Krasnyansky <maxk@qualcomm.com>
This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License version 2 as published by the Free Software Foundation;
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF THIRD PARTY RIGHTS. IN NO EVENT SHALL THE COPYRIGHT HOLDER(S) AND AUTHOR(S) BE LIABLE FOR ANY CLAIM, OR ANY SPECIAL INDIRECT OR CONSEQUENTIAL DAMAGES, OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
ALL LIABILITY, INCLUDING LIABILITY FOR INFRINGEMENT OF ANY PATENTS, COPYRIGHTS, TRADEMARKS OR OTHER RIGHTS, RELATING TO USE OF THIS SOFTWARE IS DISCLAIMED.
*/
/* It is possible that we receive Inquiry Complete event right * before we receive Inquiry Cancel Command Complete event, in * which case the latter event should have status of Command * Disallowed. This should not be treated as error, since * we actually achieve what Inquiry Cancel wants to achieve, * which is to end the last Inquiry session.
*/ if (rp->status == HCI_ERROR_COMMAND_DISALLOWED && !test_bit(HCI_INQUIRY, &hdev->flags)) {
bt_dev_warn(hdev, "Ignoring error of Inquiry Cancel command");
rp->status = 0x00;
}
if (rp->status) return rp->status;
clear_bit(HCI_INQUIRY, &hdev->flags);
smp_mb__after_atomic(); /* wake_up_bit advises about this barrier */
wake_up_bit(&hdev->flags, HCI_INQUIRY);
hci_dev_lock(hdev); /* Set discovery state to stopped if we're not doing LE active * scanning.
*/ if (!hci_dev_test_flag(hdev, HCI_LE_SCAN) ||
hdev->le_scan_type != LE_SCAN_ACTIVE)
hci_discovery_set_state(hdev, DISCOVERY_STOPPED);
hci_dev_unlock(hdev);
conn = hci_conn_hash_lookup_handle(hdev, handle); if (!conn) {
status = 0xFF; goto done;
}
/* While unexpected, the read_enc_key_size command may fail. The most * secure approach is to then assume the key size is 0 to force a * disconnection.
*/ if (status) {
bt_dev_err(hdev, "failed to read key size for handle %u",
handle);
conn->enc_key_size = 0;
} else {
u8 *key_enc_size = hci_conn_key_enc_size(conn);
conn->enc_key_size = rp->key_size;
status = 0;
/* Attempt to check if the key size is too small or if it has * been downgraded from the last time it was stored as part of * the link_key.
*/ if (conn->enc_key_size < hdev->min_enc_key_size ||
(key_enc_size && conn->enc_key_size < *key_enc_size)) { /* As slave role, the conn->state has been set to * BT_CONNECTED and l2cap conn req might not be received * yet, at this moment the l2cap layer almost does * nothing with the non-zero status. * So we also clear encrypt related bits, and then the * handler of l2cap conn req will get the right secure * state at a later time.
*/
status = HCI_ERROR_AUTH_FAILURE;
clear_bit(HCI_CONN_ENCRYPT, &conn->flags);
clear_bit(HCI_CONN_AES_CCM, &conn->flags);
}
/* Update the key encryption size with the connection one */ if (key_enc_size && *key_enc_size != conn->enc_key_size)
*key_enc_size = conn->enc_key_size;
}
if (hdev->max_page < rp->max_page) { if (hci_test_quirk(hdev,
HCI_QUIRK_BROKEN_LOCAL_EXT_FEATURES_PAGE_2))
bt_dev_warn(hdev, "broken local ext features page 2"); else
hdev->max_page = rp->max_page;
}
if (rp->page < HCI_MAX_PAGES)
memcpy(hdev->features[rp->page], rp->features, 8);
cp = hci_sent_cmd_data(hdev, HCI_OP_LE_SET_ADV_SET_RAND_ADDR); /* Update only in case the adv instance since handle 0x00 shall be using * HCI_OP_LE_SET_RANDOM_ADDR since that allows both extended and * non-extended adverting.
*/ if (!cp || !cp->handle) return rp->status;
cp = hci_sent_cmd_data(hdev, HCI_OP_LE_SET_EXT_ADV_ENABLE); if (!cp) return rp->status;
set = (void *)cp->data;
hci_dev_lock(hdev);
if (cp->num_of_sets)
adv = hci_find_adv_instance(hdev, set->handle);
if (cp->enable) { struct hci_conn *conn;
hci_dev_set_flag(hdev, HCI_LE_ADV);
if (adv)
adv->enabled = true; elseif (!set->handle)
hci_dev_set_flag(hdev, HCI_LE_ADV_0);
conn = hci_lookup_le_connect(hdev); if (conn)
queue_delayed_work(hdev->workqueue,
&conn->le_conn_timeout,
conn->conn_timeout);
} else { if (cp->num_of_sets) { if (adv)
adv->enabled = false; elseif (!set->handle)
hci_dev_clear_flag(hdev, HCI_LE_ADV_0);
/* If just one instance was disabled check if there are * any other instance enabled before clearing HCI_LE_ADV
*/
list_for_each_entry_safe(adv, n, &hdev->adv_instances,
list) { if (adv->enabled) goto unlock;
}
} else { /* All instances shall be considered disabled */
list_for_each_entry_safe(adv, n, &hdev->adv_instances,
list)
adv->enabled = false;
}
switch (enable) { case LE_SCAN_ENABLE:
hci_dev_set_flag(hdev, HCI_LE_SCAN); if (hdev->le_scan_type == LE_SCAN_ACTIVE) {
clear_pending_adv_report(hdev);
hci_discovery_set_state(hdev, DISCOVERY_FINDING);
} break;
case LE_SCAN_DISABLE: /* We do this here instead of when setting DISCOVERY_STOPPED * since the latter would potentially require waiting for * inquiry to stop too.
*/ if (has_pending_adv_report(hdev)) { struct discovery_state *d = &hdev->discovery;
/* Cancel this timer so that we don't try to disable scanning * when it's already disabled.
*/
cancel_delayed_work(&hdev->le_scan_disable);
hci_dev_clear_flag(hdev, HCI_LE_SCAN);
/* The HCI_LE_SCAN_INTERRUPTED flag indicates that we * interrupted scanning due to a connect request. Mark * therefore discovery as stopped.
*/ if (hci_dev_test_and_clear_flag(hdev, HCI_LE_SCAN_INTERRUPTED))
hci_discovery_set_state(hdev, DISCOVERY_STOPPED); elseif (!hci_dev_test_flag(hdev, HCI_LE_ADV) &&
hdev->discovery.state == DISCOVERY_FINDING)
queue_work(hdev->workqueue, &hdev->reenable_adv_work);
if (conn->pending_sec_level == BT_SECURITY_SDP) return 0;
/* Only request authentication for SSP connections or non-SSP * devices with sec_level MEDIUM or HIGH or if MITM protection * is requested.
*/ if (!hci_conn_ssp_enabled(conn) && !(conn->auth_type & 0x01) &&
conn->pending_sec_level != BT_SECURITY_FIPS &&
conn->pending_sec_level != BT_SECURITY_HIGH &&
conn->pending_sec_level != BT_SECURITY_MEDIUM) return 0;
/* We should stop if we already spent too much time resolving names. */ if (time_after(jiffies, discov->name_resolve_timeout)) {
bt_dev_warn_ratelimited(hdev, "Name resolve takes too long."); returnfalse;
}
e = hci_inquiry_cache_lookup_resolve(hdev, BDADDR_ANY, NAME_NEEDED); if (!e) returnfalse;
/* Update the mgmt connected state if necessary. Be careful with * conn objects that exist but are not (yet) connected however. * Only those in BT_CONFIG or BT_CONNECTED states can be * considered connected.
*/ if (conn && (conn->state == BT_CONFIG || conn->state == BT_CONNECTED))
mgmt_device_connected(hdev, conn, name, name_len);
if (discov->state == DISCOVERY_STOPPED) return;
if (discov->state == DISCOVERY_STOPPING) goto discov_complete;
if (discov->state != DISCOVERY_RESOLVING) return;
e = hci_inquiry_cache_lookup_resolve(hdev, bdaddr, NAME_PENDING); /* If the device was not found in a list of found devices names of which * are pending. there is no need to continue resolving a next name as it * will be done upon receiving another Remote Name Request Complete
* Event */ if (!e) return;
/* Wait for HCI_EV_DISCONN_COMPLETE if status 0x00 and not suspended * otherwise cleanup the connection immediately.
*/ if (!status && !hdev->suspended) return;
cp = hci_sent_cmd_data(hdev, HCI_OP_DISCONNECT); if (!cp) return;
hci_dev_lock(hdev);
conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(cp->handle)); if (!conn) goto unlock;
if (status && status != HCI_ERROR_UNKNOWN_CONN_ID) {
mgmt_disconnect_failed(hdev, &conn->dst, conn->type,
conn->dst_type, status);
/* Inform sockets conn is gone before we delete it */
hci_disconn_cfm(conn, HCI_ERROR_UNSPECIFIED);
goto done;
}
/* During suspend, mark connection as closed immediately * since we might not receive HCI_EV_DISCONN_COMPLETE
*/ if (hdev->suspended)
conn->state = BT_CLOSED;
done: /* If the disconnection failed for any reason, the upper layer * does not retry to disconnect in current implementation. * Hence, we need to do some basic cleanup here and re-enable * advertising if necessary.
*/
hci_conn_del(conn);
unlock:
hci_dev_unlock(hdev);
}
static u8 ev_bdaddr_type(struct hci_dev *hdev, u8 type, bool *resolved)
{ /* When using controller based address resolution, then the new * address types 0x02 and 0x03 are used. These types need to be * converted back into either public address or random address type
*/ switch (type) { case ADDR_LE_DEV_PUBLIC_RESOLVED: if (resolved)
*resolved = true; return ADDR_LE_DEV_PUBLIC; case ADDR_LE_DEV_RANDOM_RESOLVED: if (resolved)
*resolved = true; return ADDR_LE_DEV_RANDOM;
}
/* 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);
/* All connection failure handling is taken care of by the * hci_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;
/* All connection failure handling is taken care of by the * hci_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_EXT_CREATE_CONN); if (!cp) return;
if (!test_and_clear_bit(HCI_INQUIRY, &hdev->flags)) return;
smp_mb__after_atomic(); /* wake_up_bit advises about this barrier */
wake_up_bit(&hdev->flags, HCI_INQUIRY);
if (!hci_dev_test_flag(hdev, HCI_MGMT)) return;
hci_dev_lock(hdev);
if (discov->state != DISCOVERY_FINDING) goto unlock;
if (list_empty(&discov->resolve)) { /* When BR/EDR inquiry is active and no LE scanning is in * progress, then change discovery state to indicate completion. * * When running LE scanning and BR/EDR inquiry simultaneously * and the LE scan already finished, then change the discovery * state to indicate completion.
*/ if (!hci_dev_test_flag(hdev, HCI_LE_SCAN) ||
!hci_test_quirk(hdev, HCI_QUIRK_SIMULTANEOUS_DISCOVERY))
hci_discovery_set_state(hdev, DISCOVERY_STOPPED); goto unlock;
}
e = hci_inquiry_cache_lookup_resolve(hdev, BDADDR_ANY, NAME_NEEDED); if (e && hci_resolve_name(hdev, e) == 0) {
e->name_state = NAME_PENDING;
hci_discovery_set_state(hdev, DISCOVERY_RESOLVING);
discov->name_resolve_timeout = jiffies + NAME_RESOLVE_DURATION;
} else { /* When BR/EDR inquiry is active and no LE scanning is in * progress, then change discovery state to indicate completion. * * When running LE scanning and BR/EDR inquiry simultaneously * and the LE scan already finished, then change the discovery * state to indicate completion.
*/ if (!hci_dev_test_flag(hdev, HCI_LE_SCAN) ||
!hci_test_quirk(hdev, HCI_QUIRK_SIMULTANEOUS_DISCOVERY))
hci_discovery_set_state(hdev, DISCOVERY_STOPPED);
}
/* If the key enc_size is already known, use it as conn->enc_key_size, * otherwise use hdev->min_enc_key_size so the likes of * l2cap_check_enc_key_size don't fail while waiting for * HCI_OP_READ_ENC_KEY_SIZE response.
*/ if (key_enc_size && *key_enc_size)
conn->enc_key_size = *key_enc_size; else
conn->enc_key_size = hdev->min_enc_key_size;
/* Check for existing connection: * * 1. If it doesn't exist then it must be receiver/slave role. * 2. If it does exist confirm that it is connecting/BT_CONNECT in case * of initiator/master role since there could be a collision where * either side is attempting to connect or something like a fuzzing * testing is trying to play tricks to destroy the hcon object before * it even attempts to connect (e.g. hcon->state == BT_OPEN).
*/
conn = hci_conn_hash_lookup_ba(hdev, ev->link_type, &ev->bdaddr); if (!conn ||
(conn->role == HCI_ROLE_MASTER && conn->state != BT_CONNECT)) { /* In case of error status and there is no connection pending * just unlock as there is nothing to cleanup.
*/ if (ev->status) goto unlock;
/* Connection may not exist if auto-connected. Check the bredr * allowlist to see if this device is allowed to auto connect. * If link is an ACL type, create a connection class * automatically. * * Auto-connect will only occur if the event filter is * programmed with a given address. Right now, event filter is * only used during suspend.
*/ if (ev->link_type == ACL_LINK &&
hci_bdaddr_list_lookup_with_flags(&hdev->accept_list,
&ev->bdaddr,
BDADDR_BREDR)) {
conn = hci_conn_add_unset(hdev, ev->link_type,
&ev->bdaddr, HCI_ROLE_SLAVE); if (IS_ERR(conn)) {
bt_dev_err(hdev, "connection err: %ld", PTR_ERR(conn)); goto unlock;
}
} else { if (ev->link_type != SCO_LINK) goto unlock;
conn = hci_conn_hash_lookup_ba(hdev, ESCO_LINK,
&ev->bdaddr); if (!conn) goto unlock;
conn->type = SCO_LINK;
}
}
/* The HCI_Connection_Complete event is only sent once per connection. * Processing it more than once per connection can corrupt kernel memory. * * As the connection handle is set here for the first time, it indicates * whether the connection is already set up.
*/ if (!HCI_CONN_HANDLE_UNSET(conn->handle)) {
bt_dev_err(hdev, "Ignoring HCI_Connection_Complete for existing connection"); goto unlock;
}
if (!status) {
status = hci_conn_set_handle(conn, __le16_to_cpu(ev->handle)); if (status) goto done;
if (conn->type == ACL_LINK) {
conn->state = BT_CONFIG;
hci_conn_hold(conn);
bt_dev_dbg(hdev, "bdaddr %pMR type 0x%x", &ev->bdaddr, ev->link_type);
/* Reject incoming connection from device with same BD ADDR against * CVE-2020-26555
*/ if (hdev && !bacmp(&hdev->bdaddr, &ev->bdaddr)) {
bt_dev_dbg(hdev, "Reject connection with same BD_ADDR %pMR\n",
&ev->bdaddr);
hci_reject_conn(hdev, &ev->bdaddr); return;
}
if (!(mask & HCI_LM_ACCEPT)) {
hci_reject_conn(hdev, &ev->bdaddr); return;
}
hci_dev_lock(hdev);
if (hci_bdaddr_list_lookup(&hdev->reject_list, &ev->bdaddr,
BDADDR_BREDR)) {
hci_reject_conn(hdev, &ev->bdaddr); goto unlock;
}
/* Require HCI_CONNECTABLE or an accept list entry to accept the * connection. These features are only touched through mgmt so * only do the checks if HCI_MGMT is set.
*/ if (hci_dev_test_flag(hdev, HCI_MGMT) &&
!hci_dev_test_flag(hdev, HCI_CONNECTABLE) &&
!hci_bdaddr_list_lookup_with_flags(&hdev->accept_list, &ev->bdaddr,
BDADDR_BREDR)) {
hci_reject_conn(hdev, &ev->bdaddr); goto unlock;
}
/* Connection accepted */
ie = hci_inquiry_cache_lookup(hdev, &ev->bdaddr); if (ie)
memcpy(ie->data.dev_class, ev->dev_class, 3);
if (conn->type == ACL_LINK) { if (test_and_clear_bit(HCI_CONN_FLUSH_KEY, &conn->flags))
hci_remove_link_key(hdev, &conn->dst);
hci_update_scan(hdev);
}
/* Re-enable passive scanning if disconnected device is marked * as auto-connectable.
*/ if (conn->type == LE_LINK) {
params = hci_conn_params_lookup(hdev, &conn->dst,
conn->dst_type); if (params) { switch (params->auto_connect) { case HCI_AUTO_CONN_LINK_LOSS: if (ev->reason != HCI_ERROR_CONNECTION_TIMEOUT) break;
fallthrough;
case HCI_AUTO_CONN_DIRECT: case HCI_AUTO_CONN_ALWAYS:
hci_pend_le_list_del_init(params);
hci_pend_le_list_add(params,
&hdev->pend_le_conns);
hci_update_passive_scan(hdev); break;
default: break;
}
}
}
hci_disconn_cfm(conn, ev->reason);
/* Re-enable advertising if necessary, since it might * have been disabled by the connection. From the * HCI_LE_Set_Advertise_Enable command description in * the core specification (v4.0): * "The Controller shall continue advertising until the Host * issues an LE_Set_Advertise_Enable command with * Advertising_Enable set to 0x00 (Advertising is disabled) * or until a connection is created or until the Advertising * is timed out due to Directed Advertising."
*/ if (conn->type == LE_LINK && conn->role == HCI_ROLE_SLAVE) {
hdev->cur_adv_instance = conn->adv_instance;
hci_enable_advertising(hdev);
}
/* We should disregard the current RPA and generate a new one * whenever the encryption procedure fails.
*/ if (ev->status && conn->type == LE_LINK) {
hci_dev_set_flag(hdev, HCI_RPA_EXPIRED);
hci_adv_instances_set_rpa_expired(hdev, true);
}
clear_bit(HCI_CONN_ENCRYPT_PEND, &conn->flags);
/* Check link security requirements are met */ if (!hci_conn_check_link_mode(conn))
ev->status = HCI_ERROR_AUTH_FAILURE;
if (ev->status && conn->state == BT_CONNECTED) { if (ev->status == HCI_ERROR_PIN_OR_KEY_MISSING)
set_bit(HCI_CONN_AUTH_FAILURE, &conn->flags);
/* Notify upper layers so they can cleanup before * disconnecting.
*/
hci_encrypt_cfm(conn, ev->status);
hci_disconnect(conn, HCI_ERROR_AUTH_FAILURE);
hci_conn_drop(conn); goto unlock;
}
/* Try reading the encryption key size for encrypted ACL links */ if (!ev->status && ev->encrypt && conn->type == ACL_LINK) { if (hci_read_enc_key_size(hdev, conn)) goto notify;
goto unlock;
}
/* We skip the WRITE_AUTH_PAYLOAD_TIMEOUT for ATS2851 based controllers * to avoid unexpected SMP command errors when pairing.
*/ if (hci_test_quirk(hdev, HCI_QUIRK_BROKEN_WRITE_AUTH_PAYLOAD_TIMEOUT)) goto notify;
/* Set the default Authenticated Payload Timeout after * an LE Link is established. As per Core Spec v5.0, Vol 2, Part B * Section 3.3, the HCI command WRITE_AUTH_PAYLOAD_TIMEOUT should be * sent when the link is active and Encryption is enabled, the conn * type can be either LE or ACL and controller must support LMP Ping. * Ensure for AES-CCM encryption as well.
*/ if (test_bit(HCI_CONN_ENCRYPT, &conn->flags) &&
test_bit(HCI_CONN_AES_CCM, &conn->flags) &&
((conn->type == ACL_LINK && lmp_ping_capable(hdev)) ||
(conn->type == LE_LINK && (hdev->le_features[0] & HCI_LE_PING)))) { struct hci_cp_write_auth_payload_to cp;
cp = hci_sent_cmd_data(hdev, HCI_OP_LE_SET_CIG_PARAMS); if (!rp->status && (!cp || rp->num_handles != cp->num_cis ||
rp->cig_id != cp->cig_id)) {
bt_dev_err(hdev, "unexpected Set CIG Parameters response data");
status = HCI_ERROR_UNSPECIFIED;
}
hci_dev_lock(hdev);
/* BLUETOOTH CORE SPECIFICATION Version 5.4 | Vol 4, Part E page 2554 * * If the Status return parameter is non-zero, then the state of the CIG * and its CIS configurations shall not be changed by the command. If * the CIG did not already exist, it shall not be created.
*/ if (status) { /* Keep current configuration, fail only the unbound CIS */
hci_unbound_cis_failed(hdev, rp->cig_id, status); goto unlock;
}
/* BLUETOOTH CORE SPECIFICATION Version 5.3 | Vol 4, Part E page 2553 * * If the Status return parameter is zero, then the Controller shall * set the Connection_Handle arrayed return parameter to the connection * handle(s) corresponding to the CIS configurations specified in * the CIS_IDs command parameter, in the same order.
*/ for (i = 0; i < rp->num_handles; ++i) {
conn = hci_conn_hash_lookup_cis(hdev, NULL, 0, rp->cig_id,
cp->cis[i].cis_id); if (!conn || !bacmp(&conn->dst, BDADDR_ANY)) continue;
if (conn->state != BT_BOUND && conn->state != BT_CONNECT) continue;
if (hci_conn_set_handle(conn, __le16_to_cpu(rp->handle[i]))) continue;
if (conn->state == BT_CONNECT)
pending = true;
}
unlock: if (pending)
hci_le_create_cis_pending(hdev);
cp = hci_sent_cmd_data(hdev, HCI_OP_LE_SETUP_ISO_PATH); if (!cp) return rp->status;
hci_dev_lock(hdev);
conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(cp->handle)); if (!conn) goto unlock;
if (rp->status) {
hci_connect_cfm(conn, rp->status);
hci_conn_del(conn); goto unlock;
}
switch (cp->direction) { /* Input (Host to Controller) */ case 0x00: /* Only confirm connection if output only */ if (conn->iso_qos.ucast.out.sdu && !conn->iso_qos.ucast.in.sdu)
hci_connect_cfm(conn, rp->status); break; /* Output (Controller to Host) */ case 0x01: /* Confirm connection since conn->iso_qos is always configured * last.
*/
hci_connect_cfm(conn, rp->status);
/* Notify device connected in case it is a BIG Sync */ if (!rp->status && test_bit(HCI_CONN_BIG_SYNC, &conn->flags))
mgmt_device_connected(hdev, conn, NULL, 0);
cp = hci_sent_cmd_data(hdev, HCI_OP_LE_SET_PER_ADV_ENABLE); if (!cp) return rp->status;
hci_dev_lock(hdev);
adv = hci_find_adv_instance(hdev, cp->handle);
if (cp->enable) {
hci_dev_set_flag(hdev, HCI_LE_PER_ADV);
if (adv)
adv->periodic_enabled = true;
} else { if (adv)
adv->periodic_enabled = false;
/* If just one instance was disabled check if there are * any other instance enabled before clearing HCI_LE_PER_ADV. * The current periodic adv instance will be marked as * disabled once extended advertising is also disabled.
*/
list_for_each_entry_safe(adv, n, &hdev->adv_instances,
list) { if (adv->periodic && adv->enabled)
per_adv_cnt++;
}
if (skb->len < cc->min_len) {
bt_dev_err(hdev, "unexpected cc 0x%4.4x length: %u < %u",
cc->op, skb->len, cc->min_len); return HCI_ERROR_UNSPECIFIED;
}
/* Just warn if the length is over max_len size it still be possible to * partially parse the cc so leave to callback to decide if that is * acceptable.
*/ if (skb->len > cc->max_len)
bt_dev_warn(hdev, "unexpected cc 0x%4.4x length: %u > %u",
cc->op, skb->len, cc->max_len);
data = hci_cc_skb_pull(hdev, skb, cc->op, cc->min_len); if (!data) return HCI_ERROR_UNSPECIFIED;
for (i = 0; i < ARRAY_SIZE(hci_cc_table); i++) { if (hci_cc_table[i].op == *opcode) {
*status = hci_cc_func(hdev, &hci_cc_table[i], skb); break;
}
}
if (i == ARRAY_SIZE(hci_cc_table)) { if (!skb->len) {
bt_dev_err(hdev, "Unexpected cc 0x%4.4x with no status",
*opcode);
*status = HCI_ERROR_UNSPECIFIED; return;
}
/* Unknown opcode, assume byte 0 contains the status, so * that e.g. __hci_cmd_sync() properly returns errors * for vendor specific commands send by HCI drivers. * If a vendor doesn't actually follow this convention we may * need to introduce a vendor CC table in order to properly set * the status.
*/
*status = skb->data[0];
}
for (i = 0; i < ARRAY_SIZE(hci_cs_table); i++) { if (hci_cs_table[i].op == *opcode) {
hci_cs_table[i].func(hdev, ev->status); break;
}
}
handle_cmd_cnt_and_timer(hdev, ev->ncmd);
/* Indicate request completion if the command failed. Also, if * we're not waiting for a special event and we get a success * command status we should try to flag the request as completed * (since for this kind of commands there will not be a command * complete event).
*/ if (ev->status || (hdev->req_skb && !hci_skb_event(hdev->req_skb))) {
hci_req_cmd_complete(hdev, *opcode, ev->status, req_complete,
req_complete_skb); if (hci_dev_test_flag(hdev, HCI_CMD_PENDING)) {
bt_dev_err(hdev, "unexpected event for opcode 0x%4.4x",
*opcode); return;
}
}
if (atomic_read(&hdev->cmd_cnt) && !skb_queue_empty(&hdev->cmd_q))
queue_work(hdev->workqueue, &hdev->cmd_work);
}
conn = hci_conn_hash_lookup_handle(hdev, handle); if (!conn) continue;
/* Check if there is really enough packets outstanding before * attempting to decrease the sent counter otherwise it could * underflow..
*/ if (conn->sent >= count) {
conn->sent -= count;
} else {
bt_dev_warn(hdev, "hcon %p sent %u < count %u",
conn, conn->sent, count);
conn->sent = 0;
}
for (i = 0; i < count; ++i)
hci_conn_tx_dequeue(conn);
switch (conn->type) { case ACL_LINK:
hdev->acl_cnt += count; if (hdev->acl_cnt > hdev->acl_pkts)
hdev->acl_cnt = hdev->acl_pkts; break;
case LE_LINK: if (hdev->le_pkts) {
hdev->le_cnt += count; if (hdev->le_cnt > hdev->le_pkts)
hdev->le_cnt = hdev->le_pkts;
} else {
hdev->acl_cnt += count; if (hdev->acl_cnt > hdev->acl_pkts)
hdev->acl_cnt = hdev->acl_pkts;
} break;
case SCO_LINK: case ESCO_LINK:
hdev->sco_cnt += count; if (hdev->sco_cnt > hdev->sco_pkts)
hdev->sco_cnt = hdev->sco_pkts;
break;
case CIS_LINK: case BIS_LINK: case PA_LINK: if (hdev->iso_pkts) {
hdev->iso_cnt += count; if (hdev->iso_cnt > hdev->iso_pkts)
hdev->iso_cnt = hdev->iso_pkts;
} elseif (hdev->le_pkts) {
hdev->le_cnt += count; if (hdev->le_cnt > hdev->le_pkts)
hdev->le_cnt = hdev->le_pkts;
} else {
hdev->acl_cnt += count; if (hdev->acl_cnt > hdev->acl_pkts)
hdev->acl_cnt = hdev->acl_pkts;
} break;
/* Update connection information since adding the key will have * fixed up the type in the case of changed combination keys.
*/ if (ev->key_type == HCI_LK_CHANGED_COMBINATION)
conn_set_key(conn, key->type, key->pin_len);
mgmt_new_link_key(hdev, key, persistent);
/* Keep debug keys around only if the HCI_KEEP_DEBUG_KEYS flag * is set. If it's not set simply remove the key from the kernel * list (we've still notified user space about it but with * store_hint being 0).
*/ if (key->type == HCI_LK_DEBUG_COMBINATION &&
!hci_dev_test_flag(hdev, HCI_KEEP_DEBUG_KEYS)) {
list_del_rcu(&key->list);
kfree_rcu(key, rcu); goto unlock;
}
if (persistent)
clear_bit(HCI_CONN_FLUSH_KEY, &conn->flags); else
set_bit(HCI_CONN_FLUSH_KEY, &conn->flags);
if (ev->features[0] & LMP_HOST_SSP) {
set_bit(HCI_CONN_SSP_ENABLED, &conn->flags);
} else { /* It is mandatory by the Bluetooth specification that * Extended Inquiry Results are only used when Secure * Simple Pairing is enabled, but some devices violate * this. * * To make these devices work, the internal SSP * enabled flag needs to be cleared if the remote host
* features do not indicate SSP support */
clear_bit(HCI_CONN_SSP_ENABLED, &conn->flags);
}
if (ev->features[0] & LMP_HOST_SC)
set_bit(HCI_CONN_SC_ENABLED, &conn->flags);
}
switch (ev->link_type) { case SCO_LINK: case ESCO_LINK: break; default: /* As per Core 5.3 Vol 4 Part E 7.7.35 (p.2219), Link_Type * for HCI_Synchronous_Connection_Complete is limited to * either SCO or eSCO
*/
bt_dev_err(hdev, "Ignoring connect complete event for invalid link type"); return;
}
bt_dev_dbg(hdev, "status 0x%2.2x", status);
hci_dev_lock(hdev);
conn = hci_conn_hash_lookup_ba(hdev, ev->link_type, &ev->bdaddr); if (!conn) { if (ev->link_type == ESCO_LINK) goto unlock;
/* When the link type in the event indicates SCO connection * and lookup of the connection object fails, then check * if an eSCO connection object exists. * * The core limits the synchronous connections to either * SCO or eSCO. The eSCO connection is preferred and tried * to be setup first and until successfully established, * the link type will be hinted as eSCO.
*/
conn = hci_conn_hash_lookup_ba(hdev, ESCO_LINK, &ev->bdaddr); if (!conn) goto unlock;
}
/* The HCI_Synchronous_Connection_Complete event is only sent once per connection. * Processing it more than once per connection can corrupt kernel memory. * * As the connection handle is set here for the first time, it indicates * whether the connection is already set up.
*/ if (!HCI_CONN_HANDLE_UNSET(conn->handle)) {
bt_dev_err(hdev, "Ignoring HCI_Sync_Conn_Complete event for existing connection"); goto unlock;
}
switch (status) { case 0x00:
status = hci_conn_set_handle(conn, __le16_to_cpu(ev->handle)); if (status) {
conn->state = BT_CLOSED; break;
}
case 0x10: /* Connection Accept Timeout */ case 0x0d: /* Connection Rejected due to Limited Resources */ case 0x11: /* Unsupported Feature or Parameter Value */ case 0x1c: /* SCO interval rejected */ case 0x1a: /* Unsupported Remote Feature */ case 0x1e: /* Invalid LMP Parameters */ case 0x1f: /* Unspecified error */ case 0x20: /* Unsupported LMP Parameter value */ if (conn->out) {
conn->pkt_type = (hdev->esco_type & SCO_ESCO_MASK) |
(hdev->esco_type & EDR_ESCO_MASK); if (hci_setup_sync(conn, conn->parent->handle)) goto unlock;
}
fallthrough;
default:
conn->state = BT_CLOSED; break;
}
bt_dev_dbg(hdev, "SCO connected with air mode: %02x", ev->air_mode); /* Notify only in case of SCO over HCI transport data path which * is zero and non-zero value shall be non-HCI transport data path
*/ if (conn->codec.data_path == 0 && hdev->notify) { switch (ev->air_mode) { case 0x02:
hdev->notify(hdev, HCI_NOTIFY_ENABLE_SCO_CVSD); break; case 0x03:
hdev->notify(hdev, HCI_NOTIFY_ENABLE_SCO_TRANSP); break;
}
}
hci_connect_cfm(conn, status); if (status)
hci_conn_del(conn);
static u8 hci_get_auth_req(struct hci_conn *conn)
{ /* If remote requests no-bonding follow that lead */ if (conn->remote_auth == HCI_AT_NO_BONDING ||
conn->remote_auth == HCI_AT_NO_BONDING_MITM) return conn->remote_auth | (conn->auth_type & 0x01);
/* If both remote and local have enough IO capabilities, require * MITM protection
*/ if (conn->remote_cap != HCI_IO_NO_INPUT_OUTPUT &&
conn->io_capability != HCI_IO_NO_INPUT_OUTPUT) return conn->remote_auth | 0x01;
/* No MITM protection possible so ignore remote requirement */ return (conn->remote_auth & ~0x01) | (conn->auth_type & 0x01);
}
data = hci_find_remote_oob_data(hdev, &conn->dst, BDADDR_BREDR); if (!data) return 0x00;
if (bredr_sc_enabled(hdev)) { /* When Secure Connections is enabled, then just * return the present value stored with the OOB * data. The stored value contains the right present * information. However it can only be trusted when * not in Secure Connection Only mode.
*/ if (!hci_dev_test_flag(hdev, HCI_SC_ONLY)) return data->present;
/* When Secure Connections Only mode is enabled, then * the P-256 values are required. If they are not * available, then do not declare that OOB data is * present.
*/ if (!crypto_memneq(data->rand256, ZERO_KEY, 16) ||
!crypto_memneq(data->hash256, ZERO_KEY, 16)) return 0x00;
return 0x02;
}
/* When Secure Connections is not enabled or actually * not supported by the hardware, then check that if * P-192 data values are present.
*/ if (!crypto_memneq(data->rand192, ZERO_KEY, 16) ||
!crypto_memneq(data->hash192, ZERO_KEY, 16)) return 0x00;
/* Assume remote supports SSP since it has triggered this event */
set_bit(HCI_CONN_SSP_ENABLED, &conn->flags);
hci_conn_hold(conn);
if (!hci_dev_test_flag(hdev, HCI_MGMT)) goto unlock;
/* Allow pairing if we're pairable, the initiators of the * pairing or if the remote is not requesting bonding.
*/ if (hci_dev_test_flag(hdev, HCI_BONDABLE) ||
test_bit(HCI_CONN_AUTH_INITIATOR, &conn->flags) ||
(conn->remote_auth & ~0x01) == HCI_AT_NO_BONDING) { struct hci_cp_io_capability_reply cp;
bacpy(&cp.bdaddr, &ev->bdaddr); /* Change the IO capability from KeyboardDisplay
* to DisplayYesNo as it is not supported by BT spec. */
cp.capability = (conn->io_capability == 0x04) ?
HCI_IO_DISPLAY_YESNO : conn->io_capability;
/* If we are initiators, there is no remote information yet */ if (conn->remote_auth == 0xff) { /* Request MITM protection if our IO caps allow it * except for the no-bonding case.
*/ if (conn->io_capability != HCI_IO_NO_INPUT_OUTPUT &&
conn->auth_type != HCI_AT_NO_BONDING)
conn->auth_type |= 0x01;
} else {
conn->auth_type = hci_get_auth_req(conn);
}
/* If we're not bondable, force one of the non-bondable * authentication requirement values.
*/ if (!hci_dev_test_flag(hdev, HCI_BONDABLE))
conn->auth_type &= HCI_AT_NO_BONDING_MITM;
/* If we require MITM but the remote device can't provide that * (it has NoInputNoOutput) then reject the confirmation * request. We check the security level here since it doesn't * necessarily match conn->auth_type.
*/ if (conn->pending_sec_level > BT_SECURITY_MEDIUM &&
conn->remote_cap == HCI_IO_NO_INPUT_OUTPUT) {
bt_dev_dbg(hdev, "Rejecting request: remote device can't provide MITM");
hci_send_cmd(hdev, HCI_OP_USER_CONFIRM_NEG_REPLY, sizeof(ev->bdaddr), &ev->bdaddr); goto unlock;
}
/* If no side requires MITM protection; use JUST_CFM method */ if ((!loc_mitm || conn->remote_cap == HCI_IO_NO_INPUT_OUTPUT) &&
(!rem_mitm || conn->io_capability == HCI_IO_NO_INPUT_OUTPUT)) {
/* If we're not the initiator of request authorization and the * local IO capability is not NoInputNoOutput, use JUST_WORKS * method (mgmt_user_confirm with confirm_hint set to 1).
*/ if (!test_bit(HCI_CONN_AUTH_PEND, &conn->flags) &&
conn->io_capability != HCI_IO_NO_INPUT_OUTPUT) {
bt_dev_dbg(hdev, "Confirming auto-accept as acceptor");
confirm_hint = 1; goto confirm;
}
/* If there already exists link key in local host, leave the * decision to user space since the remote device could be * legitimate or malicious.
*/ if (hci_find_link_key(hdev, &ev->bdaddr)) {
bt_dev_dbg(hdev, "Local host already has link key");
confirm_hint = 1; goto confirm;
}
BT_DBG("Auto-accept of user confirmation with %ums delay",
hdev->auto_accept_delay);
if (hdev->auto_accept_delay > 0) { int delay = msecs_to_jiffies(hdev->auto_accept_delay);
queue_delayed_work(conn->hdev->workqueue,
&conn->auto_accept_work, delay); goto unlock;
}
/* Reset the authentication requirement to unknown */
conn->remote_auth = 0xff;
/* To avoid duplicate auth_failed events to user space we check * the HCI_CONN_AUTH_PEND flag which will be set if we * initiated the authentication. A traditional auth_complete * event gets always produced as initiator and is also mapped to
* the mgmt_auth_failed event */ if (!test_bit(HCI_CONN_AUTH_PEND, &conn->flags) && ev->status)
mgmt_auth_failed(conn, ev->status);
/* Check if the controller has set a Local RPA then it must be * used instead or hdev->rpa.
*/ if (local_rpa && bacmp(local_rpa, BDADDR_ANY)) {
conn->init_addr_type = ADDR_LE_DEV_RANDOM;
bacpy(&conn->init_addr, local_rpa);
} elseif (hci_dev_test_flag(conn->hdev, HCI_PRIVACY)) {
conn->init_addr_type = ADDR_LE_DEV_RANDOM;
bacpy(&conn->init_addr, &conn->hdev->rpa);
} else {
hci_copy_identity_address(conn->hdev, &conn->init_addr,
&conn->init_addr_type);
}
} else {
conn->resp_addr_type = conn->hdev->adv_addr_type; /* Check if the controller has set a Local RPA then it must be * used instead or hdev->rpa.
*/ if (local_rpa && bacmp(local_rpa, BDADDR_ANY)) {
conn->resp_addr_type = ADDR_LE_DEV_RANDOM;
bacpy(&conn->resp_addr, local_rpa);
} elseif (conn->hdev->adv_addr_type == ADDR_LE_DEV_RANDOM) { /* In case of ext adv, resp_addr will be updated in * Adv Terminated event.
*/ if (!ext_adv_capable(conn->hdev))
bacpy(&conn->resp_addr,
&conn->hdev->random_addr);
} else {
bacpy(&conn->resp_addr, &conn->hdev->bdaddr);
}
/* For incoming connections, set the default minimum * and maximum connection interval. They will be used * to check if the parameters are in range and if not * trigger the connection update procedure.
*/
conn->le_conn_min_interval = conn->hdev->le_conn_min_interval;
conn->le_conn_max_interval = conn->hdev->le_conn_max_interval;
}
}
/* All controllers implicitly stop advertising in the event of a * connection, so ensure that the state bit is cleared.
*/
hci_dev_clear_flag(hdev, HCI_LE_ADV);
/* Check for existing connection: * * 1. If it doesn't exist then use the role to create a new object. * 2. If it does exist confirm that it is connecting/BT_CONNECT in case * of initiator/master role since there could be a collision where * either side is attempting to connect or something like a fuzzing * testing is trying to play tricks to destroy the hcon object before * it even attempts to connect (e.g. hcon->state == BT_OPEN).
*/
conn = hci_conn_hash_lookup_role(hdev, LE_LINK, role, bdaddr); if (!conn ||
(conn->role == HCI_ROLE_MASTER && conn->state != BT_CONNECT)) { /* In case of error status and there is no connection pending * just unlock as there is nothing to cleanup.
*/ if (status) goto unlock;
/* If we didn't have a hci_conn object previously * but we're in central role this must be something * initiated using an accept list. Since accept list based * connections are not "first class citizens" we don't * have full tracking of them. Therefore, we go ahead * with a "best effort" approach of determining the * initiator address based on the HCI_PRIVACY flag.
*/ if (conn->out) {
conn->resp_addr_type = bdaddr_type;
bacpy(&conn->resp_addr, bdaddr); if (hci_dev_test_flag(hdev, HCI_PRIVACY)) {
conn->init_addr_type = ADDR_LE_DEV_RANDOM;
bacpy(&conn->init_addr, &hdev->rpa);
} else {
hci_copy_identity_address(hdev,
&conn->init_addr,
&conn->init_addr_type);
}
}
} else {
cancel_delayed_work(&conn->le_conn_timeout);
}
/* The HCI_LE_Connection_Complete event is only sent once per connection. * Processing it more than once per connection can corrupt kernel memory. * * As the connection handle is set here for the first time, it indicates * whether the connection is already set up.
*/ if (!HCI_CONN_HANDLE_UNSET(conn->handle)) {
bt_dev_err(hdev, "Ignoring HCI_Connection_Complete for existing connection"); goto unlock;
}
/* Lookup the identity address from the stored connection * address and address type. * * When establishing connections to an identity address, the * connection procedure will store the resolvable random * address first. Now if it can be converted back into the * identity address, start using the identity address from * now on.
*/
irk = hci_get_irk(hdev, &conn->dst, conn->dst_type); if (irk) {
bacpy(&conn->dst, &irk->bdaddr);
conn->dst_type = irk->addr_type;
}
/* All connection failure handling is taken care of by the * hci_conn_failed function which is triggered by the HCI * request completion callbacks used for connecting.
*/ if (status || hci_conn_set_handle(conn, handle)) goto unlock;
/* Drop the connection if it has been aborted */ if (test_bit(HCI_CONN_CANCEL, &conn->flags)) {
hci_conn_drop(conn); goto unlock;
}
/* Drop the connection if the device is blocked */ if (hci_bdaddr_list_lookup(&hdev->reject_list, &conn->dst, addr_type)) {
hci_conn_drop(conn); goto unlock;
}
/* Store current advertising instance as connection advertising instance * when software rotation is in use so it can be re-enabled when * disconnected.
*/ if (!ext_adv_capable(hdev))
conn->adv_instance = hdev->cur_adv_instance;
/* The remote features procedure is defined for central * role only. So only in case of an initiated connection * request the remote features. * * If the local controller supports peripheral-initiated features * exchange, then requesting the remote features in peripheral * role is possible. Otherwise just transition into the * connected state without requesting the remote features.
*/ if (conn->out ||
(hdev->le_features[0] & HCI_LE_PERIPHERAL_FEATURES)) { struct hci_cp_le_read_remote_features cp;
/* The Bluetooth Core 5.3 specification clearly states that this event * shall not be sent when the Host disables the advertising set. So in * case of HCI_ERROR_CANCELLED_BY_HOST, just ignore the event. * * When the Host disables an advertising set, all cleanup is done via * its command callback and not needed to be duplicated here.
*/ if (ev->status == HCI_ERROR_CANCELLED_BY_HOST) {
bt_dev_warn_ratelimited(hdev, "Unexpected advertising set terminated event"); return;
}
hci_dev_lock(hdev);
adv = hci_find_adv_instance(hdev, ev->handle);
if (ev->status) { if (!adv) goto unlock;
/* Remove advertising as it has been terminated */
hci_remove_adv_instance(hdev, ev->handle);
mgmt_advertising_removed(NULL, hdev, ev->handle);
list_for_each_entry_safe(adv, n, &hdev->adv_instances, list) { if (adv->enabled) goto unlock;
}
/* We are no longer advertising, clear HCI_LE_ADV */
hci_dev_clear_flag(hdev, HCI_LE_ADV); goto unlock;
}
if (adv)
adv->enabled = false;
conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(ev->conn_handle)); if (conn) { /* Store handle in the connection so the correct advertising * instance can be re-enabled when disconnected.
*/
conn->adv_instance = ev->handle;
if (hdev->adv_addr_type != ADDR_LE_DEV_RANDOM ||
bacmp(&conn->resp_addr, BDADDR_ANY)) goto unlock;
if (!ev->handle) {
bacpy(&conn->resp_addr, &hdev->random_addr); goto unlock;
}
if (adv)
bacpy(&conn->resp_addr, &adv->random_addr);
}
/* If the event is not connectable don't proceed further */ if (adv_type != LE_ADV_IND && adv_type != LE_ADV_DIRECT_IND) return NULL;
/* Ignore if the device is blocked or hdev is suspended */ if (hci_bdaddr_list_lookup(&hdev->reject_list, addr, addr_type) ||
hdev->suspended) return NULL;
/* Most controller will fail if we try to create new connections * while we have an existing one in peripheral role.
*/ if (hdev->conn_hash.le_num_peripheral > 0 &&
(hci_test_quirk(hdev, HCI_QUIRK_BROKEN_LE_STATES) ||
!(hdev->le_states[3] & 0x10))) return NULL;
/* 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); if (!params) return NULL;
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 peripheral 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 connections from peripheral device are * accepted and also outgoing connections to peripheral * devices are established when found.
*/ break; default: return NULL;
}
}
conn = hci_connect_le(hdev, addr, addr_type, addr_resolved,
BT_SECURITY_LOW, hdev->def_le_autoconnect_timeout,
HCI_ROLE_MASTER, phy, sec_phy); if (!IS_ERR(conn)) { /* 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.
*/
if (!params->explicit_connect)
params->conn = hci_conn_get(conn);
return conn;
}
switch (PTR_ERR(conn)) { case -EBUSY: /* If hci_connect() returns -EBUSY it means there is already * an LE connection attempt going on. Since controllers don't * support more than one connection attempt at the time, we * don't consider this an error case.
*/ break; default:
BT_DBG("Failed to connect: err %ld", PTR_ERR(conn)); return NULL;
}
switch (type) { case LE_ADV_IND: case LE_ADV_DIRECT_IND: case LE_ADV_SCAN_IND: case LE_ADV_NONCONN_IND: case LE_ADV_SCAN_RSP: break; default:
bt_dev_err_ratelimited(hdev, "unknown advertising packet " "type: 0x%02x", type); return;
}
if (len > max_adv_len(hdev)) {
bt_dev_err_ratelimited(hdev, "adv larger than maximum supported"); return;
}
/* Find the end of the data in case the report contains padded zero * bytes at the end causing an invalid length value. * * When data is NULL, len is 0 so there is no need for extra ptr * check as 'ptr < data + 0' is already false in such case.
*/ for (ptr = data; ptr < data + len && *ptr; ptr += *ptr + 1) { if (ptr + 1 + *ptr > data + len) break;
}
/* Adjust for actual length. This handles the case when remote * device is advertising with incorrect data length.
*/
len = ptr - data;
/* If the direct address is present, then this report is from * a LE Direct Advertising Report event. In that case it is * important to see if the address is matching the local * controller address. * * If local privacy is not enable the controller shall not be * generating such event since according to its documentation it is only * valid for filter_policy 0x02 and 0x03, but the fact that it did * generate LE Direct Advertising Report means it is probably broken and * won't generate any other event which can potentially break * auto-connect logic so in case local privacy is not enable this * ignores the direct_addr so it works as a regular report.
*/ if (!hci_dev_test_flag(hdev, HCI_MESH) && direct_addr &&
hci_dev_test_flag(hdev, HCI_PRIVACY)) {
direct_addr_type = ev_bdaddr_type(hdev, direct_addr_type,
&bdaddr_resolved);
/* Only resolvable random addresses are valid for these * kind of reports and others can be ignored.
*/ if (!hci_bdaddr_is_rpa(direct_addr, direct_addr_type)) return;
/* If the local IRK of the controller does not match * with the resolvable random address provided, then * this report can be ignored.
*/ if (!smp_irk_matches(hdev, hdev->irk, direct_addr)) return;
}
/* Check if we need to convert to identity address */
irk = hci_get_irk(hdev, bdaddr, bdaddr_type); if (irk) {
bdaddr = &irk->bdaddr;
bdaddr_type = irk->addr_type;
}
/* Check if we have been requested to connect to this device. * * direct_addr is set only for directed advertising reports (it is NULL * for advertising reports) and is already verified to be RPA above.
*/
conn = check_pending_le_conn(hdev, bdaddr, bdaddr_type, bdaddr_resolved,
type, phy, sec_phy); if (!ext_adv && conn && type == LE_ADV_IND &&
len <= max_adv_len(hdev)) { /* Store report for later inclusion by * mgmt_device_connected
*/
memcpy(conn->le_adv_data, data, len);
conn->le_adv_data_len = len;
}
if (type == LE_ADV_NONCONN_IND || type == LE_ADV_SCAN_IND)
flags = MGMT_DEV_FOUND_NOT_CONNECTABLE; else
flags = 0;
/* All scan results should be sent up for Mesh systems */ if (hci_dev_test_flag(hdev, HCI_MESH)) {
mgmt_device_found(hdev, bdaddr, LE_LINK, bdaddr_type, NULL,
rssi, flags, data, len, NULL, 0, instant); return;
}
/* Passive scanning shouldn't trigger any device found events, * except for devices marked as CONN_REPORT for which we do send * device found events, or advertisement monitoring requested.
*/ if (hdev->le_scan_type == LE_SCAN_PASSIVE) { if (type == LE_ADV_DIRECT_IND) return;
if (!hci_pend_le_action_lookup(&hdev->pend_le_reports,
bdaddr, bdaddr_type) &&
idr_is_empty(&hdev->adv_monitors_idr)) return;
/* When receiving a scan response, then there is no way to * know if the remote device is connectable or not. However * since scan responses are merged with a previously seen * advertising report, the flags field from that report * will be used. * * In the unlikely case that a controller just sends a scan * response event that doesn't match the pending report, then * it is marked as a standalone SCAN_RSP.
*/ if (type == LE_ADV_SCAN_RSP)
flags = MGMT_DEV_FOUND_SCAN_RSP;
/* If there's nothing pending either store the data from this * event or send an immediate device found event if the data * should not be stored for later.
*/ if (!has_pending_adv_report(hdev)) { /* If the report will trigger a SCAN_REQ store it for * later merging.
*/ if (!ext_adv && (type == LE_ADV_IND ||
type == LE_ADV_SCAN_IND)) {
store_pending_adv_report(hdev, bdaddr, bdaddr_type,
rssi, flags, data, len); return;
}
/* Check if the pending report is for the same device as the new one */
match = (!bacmp(bdaddr, &d->last_adv_addr) &&
bdaddr_type == d->last_adv_addr_type);
/* If the pending data doesn't match this report or this isn't a * scan response (e.g. we got a duplicate ADV_IND) then force * sending of the pending data.
*/ if (type != LE_ADV_SCAN_RSP || !match) { /* Send out whatever is in the cache, but skip duplicates */ if (!match)
mgmt_device_found(hdev, &d->last_adv_addr, LE_LINK,
d->last_adv_addr_type, NULL,
d->last_adv_rssi, d->last_adv_flags,
d->last_adv_data,
d->last_adv_data_len, NULL, 0, 0);
/* If the new report will trigger a SCAN_REQ store it for * later merging.
*/ if (!ext_adv && (type == LE_ADV_IND ||
type == LE_ADV_SCAN_IND)) {
store_pending_adv_report(hdev, bdaddr, bdaddr_type,
rssi, flags, data, len); return;
}
/* The advertising reports cannot be merged, so clear * the pending report and send out a device found event.
*/
clear_pending_adv_report(hdev);
mgmt_device_found(hdev, bdaddr, LE_LINK, bdaddr_type, NULL,
rssi, flags, data, len, NULL, 0, 0); return;
}
/* If we get here we've got a pending ADV_IND or ADV_SCAN_IND and * the new event is a SCAN_RSP. We can therefore proceed with * sending a merged device found event.
*/
mgmt_device_found(hdev, &d->last_adv_addr, LE_LINK,
d->last_adv_addr_type, NULL, rssi, d->last_adv_flags,
d->last_adv_data, d->last_adv_data_len, data, len, 0);
clear_pending_adv_report(hdev);
}
if (evt_type & LE_EXT_ADV_LEGACY_PDU) { switch (evt_type) { case LE_LEGACY_ADV_IND: return LE_ADV_IND; case LE_LEGACY_ADV_DIRECT_IND: return LE_ADV_DIRECT_IND; case LE_LEGACY_ADV_SCAN_IND: return LE_ADV_SCAN_IND; case LE_LEGACY_NONCONN_IND: return LE_ADV_NONCONN_IND; case LE_LEGACY_SCAN_RSP_ADV: case LE_LEGACY_SCAN_RSP_ADV_SCAN: return LE_ADV_SCAN_RSP;
}
goto invalid;
}
if (evt_type & LE_EXT_ADV_CONN_IND) { if (evt_type & LE_EXT_ADV_DIRECT_IND) return LE_ADV_DIRECT_IND;
return LE_ADV_IND;
}
if (evt_type & LE_EXT_ADV_SCAN_RSP) return LE_ADV_SCAN_RSP;
if (evt_type & LE_EXT_ADV_SCAN_IND) return LE_ADV_SCAN_IND;
if (evt_type & LE_EXT_ADV_DIRECT_IND) return LE_ADV_NONCONN_IND;
/* Check if PA Sync is pending and if the hci_conn SID has not * been set update it.
*/ if (hci_dev_test_flag(hdev, HCI_PA_SYNC)) { struct hci_conn *conn;
conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(ev->handle)); if (conn) { if (!ev->status)
memcpy(conn->features[0], ev->features, 8);
if (conn->state == BT_CONFIG) {
__u8 status;
/* If the local controller supports peripheral-initiated * features exchange, but the remote controller does * not, then it is possible that the error code 0x1a * for unsupported remote feature gets returned. * * In this specific case, allow the connection to * transition into connected state and mark it as * successful.
*/ if (!conn->out && ev->status == HCI_ERROR_UNSUPPORTED_REMOTE_FEATURE &&
(hdev->le_features[0] & HCI_LE_PERIPHERAL_FEATURES))
status = 0x00; else
status = ev->status;
conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(ev->handle)); if (conn == NULL) goto not_found;
ltk = hci_find_ltk(hdev, &conn->dst, conn->dst_type, conn->role); if (!ltk) goto not_found;
if (smp_ltk_is_sc(ltk)) { /* With SC both EDiv and Rand are set to zero */ if (ev->ediv || ev->rand) goto not_found;
} else { /* For non-SC keys check that EDiv and Rand match */ if (ev->ediv != ltk->ediv || ev->rand != ltk->rand) goto not_found;
}
/* Ref. Bluetooth Core SPEC pages 1975 and 2004. STK is a * temporary key used to encrypt a connection following * pairing. It is used during the Encrypted Session Setup to * distribute the keys. Later, security can be re-established * using a distributed LTK.
*/ if (ltk->type == SMP_STK) {
set_bit(HCI_CONN_STK_ENCRYPT, &conn->flags);
list_del_rcu(<k->list);
kfree_rcu(ltk, rcu);
} else {
clear_bit(HCI_CONN_STK_ENCRYPT, &conn->flags);
}
BT_DBG("%s status 0x%2.2x", hdev->name, ev->status);
if (!hci_le_ev_skb_pull(hdev, skb, HCI_EVT_LE_CREATE_BIG_COMPLETE,
flex_array_size(ev, bis_handle, ev->num_bis))) return;
hci_dev_lock(hdev);
/* Connect all BISes that are bound to the BIG */ while ((conn = hci_conn_hash_lookup_big_state(hdev, ev->handle,
BT_BOUND,
HCI_ROLE_MASTER))) { if (ev->status) {
hci_connect_cfm(conn, ev->status);
hci_conn_del(conn); continue;
}
if (hci_conn_set_handle(conn,
__le16_to_cpu(ev->bis_handle[i++]))) continue;
if (!ev->status && !i) /* If no BISes have been connected for the BIG, * terminate. This is in case all bound connections * have been closed before the BIG creation * has completed.
*/
hci_cmd_sync_queue(hdev, hci_iso_term_big_sync,
UINT_PTR(ev->handle), NULL);
if (!hci_le_ev_skb_pull(hdev, skb, HCI_EVT_LE_BIG_SYNC_ESTABLISHED,
flex_array_size(ev, bis, ev->num_bis))) return;
hci_dev_lock(hdev);
conn = hci_conn_hash_lookup_big_sync_pend(hdev, ev->handle,
ev->num_bis); if (!conn) {
bt_dev_err(hdev, "Unable to find connection for big 0x%2.2x",
ev->handle); goto unlock;
}
for (i = 0; i < ev->num_bis; i++) {
u16 handle = le16_to_cpu(ev->bis[i]);
__le32 interval;
bis = hci_conn_hash_lookup_handle(hdev, handle); if (!bis) { if (handle > HCI_CONN_HANDLE_MAX) {
bt_dev_dbg(hdev, "ignore too large handle %u", handle); continue;
}
bis = hci_conn_add(hdev, BIS_LINK, BDADDR_ANY,
HCI_ROLE_SLAVE, handle); if (IS_ERR(bis)) continue;
}
if (ev->status != 0x42) /* Mark PA sync as established */
set_bit(HCI_CONN_PA_SYNC, &bis->flags);
/* In case BIG sync failed, notify each failed connection to * the user after all hci connections have been added
*/ if (ev->status) for (i = 0; i < ev->num_bis; i++) {
u16 handle = le16_to_cpu(ev->bis[i]);
bis = hci_conn_hash_lookup_handle(hdev, handle); if (!bis) continue;
/* Only match event if command OGF is for LE */ if (hdev->req_skb &&
(hci_opcode_ogf(hci_skb_opcode(hdev->req_skb)) == 0x08 ||
hci_skb_opcode(hdev->req_skb) == HCI_OP_NOP) &&
hci_skb_event(hdev->req_skb) == ev->subevent) {
*opcode = hci_skb_opcode(hdev->req_skb);
hci_req_cmd_complete(hdev, *opcode, 0x00, req_complete,
req_complete_skb);
}
subev = &hci_le_ev_table[ev->subevent]; if (!subev->func) return;
/* Just warn if the length is over max_len size it still be * possible to partially parse the event so leave to callback to * decide if that is acceptable.
*/ if (skb->len > subev->max_len)
bt_dev_warn(hdev, "unexpected subevent 0x%2.2x length: %u > %u",
ev->subevent, skb->len, subev->max_len);
data = hci_le_ev_skb_pull(hdev, skb, ev->subevent, subev->min_len); if (!data) return;
hdr = hci_ev_skb_pull(hdev, skb, event, sizeof(*hdr)); if (!hdr) returnfalse;
if (event) { if (hdr->evt != event) returnfalse; returntrue;
}
/* Check if request ended in Command Status - no way to retrieve * any extra parameters in this case.
*/ if (hdr->evt == HCI_EV_CMD_STATUS) returnfalse;
if (hdr->evt != HCI_EV_CMD_COMPLETE) {
bt_dev_err(hdev, "last event is not cmd complete (0x%2.2x)",
hdr->evt); returnfalse;
}
ev = hci_cc_skb_pull(hdev, skb, opcode, sizeof(*ev)); if (!ev) returnfalse;
if (opcode != __le16_to_cpu(ev->opcode)) {
BT_DBG("opcode doesn't match (0x%2.2x != 0x%2.2x)", opcode,
__le16_to_cpu(ev->opcode)); returnfalse;
}
/* If we are currently suspended and this is the first BT event seen, * save the wake reason associated with the event.
*/ if (!hdev->suspended || hdev->wake_reason) goto unlock;
/* Default to remote wake. Values for wake_reason are documented in the * Bluez mgmt api docs.
*/
hdev->wake_reason = MGMT_WAKE_REASON_REMOTE_WAKE;
/* Once configured for remote wakeup, we should only wake up for * reconnections. It's useful to see which device is waking us up so * keep track of the bdaddr of the connection event that woke us up.
*/ if (event == HCI_EV_CONN_REQUEST) {
bacpy(&hdev->wake_addr, &conn_request->bdaddr);
hdev->wake_addr_type = BDADDR_BREDR;
} elseif (event == HCI_EV_CONN_COMPLETE) {
bacpy(&hdev->wake_addr, &conn_complete->bdaddr);
hdev->wake_addr_type = BDADDR_BREDR;
} elseif (event == HCI_EV_LE_META) { struct hci_ev_le_meta *le_ev = (void *)skb->data;
u8 subevent = le_ev->subevent;
u8 *ptr = &skb->data[sizeof(*le_ev)];
u8 num_reports = *ptr;
/* Just warn if the length is over max_len size it still be * possible to partially parse the event so leave to callback to * decide if that is acceptable.
*/ if (skb->len > ev->max_len)
bt_dev_warn_ratelimited(hdev, "unexpected event 0x%2.2x length: %u > %u",
event, skb->len, ev->max_len);
data = hci_ev_skb_pull(hdev, skb, event, ev->min_len); if (!data) return;
/* Only match event if command OGF is not for LE */ if (hdev->req_skb &&
hci_opcode_ogf(hci_skb_opcode(hdev->req_skb)) != 0x08 &&
hci_skb_event(hdev->req_skb) == event) {
hci_req_cmd_complete(hdev, hci_skb_opcode(hdev->req_skb),
status, &req_complete, &req_complete_skb);
req_evt = event;
}
/* If it looks like we might end up having to call * req_complete_skb, store a pristine copy of the skb since the * various handlers may modify the original one through * skb_pull() calls, etc.
*/ if (req_complete_skb || event == HCI_EV_CMD_STATUS ||
event == HCI_EV_CMD_COMPLETE)
orig_skb = skb_clone(skb, GFP_KERNEL);
skb_pull(skb, HCI_EVENT_HDR_SIZE);
/* Store wake reason if we're suspended */
hci_store_wake_reason(hdev, event, skb);
¤ Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.0.123Bemerkung:
(vorverarbeitet am 2026-04-28)
¤
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.