/* Grab a reference if command needs to be associated with a sock (e.g. * likely mgmt socket that initiated the command).
*/ if (sk) {
hci_skb_sk(skb) = sk;
sock_hold(sk);
}
/* If an error occurred during request building, remove all HCI * commands queued on the HCI request queue.
*/ if (req->err) {
skb_queue_purge(&req->cmd_q); return req->err;
}
/* Do not allow empty requests */ if (skb_queue_empty(&req->cmd_q)) return -ENODATA;
if (!hci_dev_test_flag(hdev, HCI_LE_SCAN)) goto _return;
status = hci_cmd_sync_queue(hdev, scan_disable_sync, NULL, NULL); if (status) {
bt_dev_err(hdev, "failed to disable LE scan: %d", status); goto _return;
}
/* If we were running LE only scan, change discovery state. If * we were running both LE and BR/EDR inquiry simultaneously, * and BR/EDR inquiry is already finished, stop discovery, * otherwise BR/EDR inquiry will stop discovery when finished. * If we will resolve remote device name, do not change * discovery state.
*/
if (hdev->discovery.type == DISCOV_TYPE_LE) goto discov_stopped;
if (hdev->discovery.type != DISCOV_TYPE_INTERLEAVED) goto _return;
if (hci_test_quirk(hdev, HCI_QUIRK_SIMULTANEOUS_DISCOVERY)) { if (!test_bit(HCI_INQUIRY, &hdev->flags) &&
hdev->discovery.state != DISCOVERY_RESOLVING) goto discov_stopped;
goto _return;
}
status = hci_cmd_sync_queue(hdev, interleaved_inquiry_sync, NULL, NULL); if (status) {
bt_dev_err(hdev, "inquiry failed: status %d", status); goto discov_stopped;
}
/* For a single instance: * - force == true: The instance will be removed even when its remaining * lifetime is not zero. * - force == false: the instance will be deactivated but kept stored unless * the remaining lifetime is zero. * * For instance == 0x00: * - force == true: All instances will be removed regardless of their timeout * setting. * - force == false: Only instances that have a timeout will be removed.
*/ int hci_clear_adv_instance_sync(struct hci_dev *hdev, struct sock *sk,
u8 instance, bool force)
{ struct adv_info *adv_instance, *n, *next_instance = NULL; int err;
u8 rem_inst;
/* Cancel any timeout concerning the removed instance(s). */ if (!instance || hdev->cur_adv_instance == instance)
cancel_adv_timeout(hdev);
/* Get the next instance to advertise BEFORE we remove * the current one. This can be the same instance again * if there is only one instance.
*/ if (instance && hdev->cur_adv_instance == instance)
next_instance = hci_get_next_instance(hdev, instance);
if (instance == 0x00) {
list_for_each_entry_safe(adv_instance, n, &hdev->adv_instances,
list) { if (!(force || adv_instance->timeout)) continue;
switch (hdev->interleave_scan_state) { case INTERLEAVE_SCAN_ALLOWLIST:
bt_dev_dbg(hdev, "next state: allowlist");
hdev->interleave_scan_state = INTERLEAVE_SCAN_NO_FILTER; break; case INTERLEAVE_SCAN_NO_FILTER:
bt_dev_dbg(hdev, "next state: no filter");
hdev->interleave_scan_state = INTERLEAVE_SCAN_ALLOWLIST; break; case INTERLEAVE_SCAN_NONE:
bt_dev_err(hdev, "unexpected error");
}
hci_dev_unlock(hdev);
/* Don't continue interleaving if it was canceled */ if (is_interleave_scanning(hdev))
queue_delayed_work(hdev->req_workqueue,
&hdev->interleave_scan, timeout);
}
/* Cancel ongoing command request synchronously: * * - Set result and mark status to HCI_REQ_CANCELED * - Wakeup command sync thread
*/ void hci_cmd_sync_cancel_sync(struct hci_dev *hdev, int err)
{
bt_dev_dbg(hdev, "err 0x%2.2x", err);
if (hdev->req_status == HCI_REQ_PEND) { /* req_result is __u32 so error must be positive to be properly * propagated.
*/
hdev->req_result = err < 0 ? -err : err;
hdev->req_status = HCI_REQ_CANCELED;
/* Submit HCI command to be run in as cmd_sync_work: * * - hdev must _not_ be unregistered
*/ int hci_cmd_sync_submit(struct hci_dev *hdev, hci_cmd_sync_work_func_t func, void *data, hci_cmd_sync_work_destroy_t destroy)
{ struct hci_cmd_sync_work_entry *entry; int err = 0;
/* Queue HCI command: * * - hdev must be running
*/ int hci_cmd_sync_queue(struct hci_dev *hdev, hci_cmd_sync_work_func_t func, void *data, hci_cmd_sync_work_destroy_t destroy)
{ /* Only queue command if hdev is running which means it had been opened * and is either on init phase or is already up.
*/ if (!test_bit(HCI_RUNNING, &hdev->flags)) return -ENETDOWN;
if (destroy && entry->destroy != destroy) continue;
return entry;
}
return NULL;
}
/* Queue HCI command entry once: * * - Lookup if an entry already exist and only if it doesn't creates a new entry * and queue it.
*/ int hci_cmd_sync_queue_once(struct hci_dev *hdev, hci_cmd_sync_work_func_t func, void *data, hci_cmd_sync_work_destroy_t destroy)
{ if (hci_cmd_sync_lookup_entry(hdev, func, data, destroy)) return 0;
/* Run HCI command: * * - hdev must be running * - if on cmd_sync_work then run immediately otherwise queue
*/ int hci_cmd_sync_run(struct hci_dev *hdev, hci_cmd_sync_work_func_t func, void *data, hci_cmd_sync_work_destroy_t destroy)
{ /* Only queue command if hdev is running which means it had been opened * and is either on init phase or is already up.
*/ if (!test_bit(HCI_RUNNING, &hdev->flags)) return -ENETDOWN;
/* If on cmd_sync_work then run immediately otherwise queue */ if (current_work() == &hdev->cmd_sync_work) return func(hdev, data);
/* Run HCI command entry once: * * - Lookup if an entry already exist and only if it doesn't creates a new entry * and run it. * - if on cmd_sync_work then run immediately otherwise queue
*/ int hci_cmd_sync_run_once(struct hci_dev *hdev, hci_cmd_sync_work_func_t func, void *data, hci_cmd_sync_work_destroy_t destroy)
{ if (hci_cmd_sync_lookup_entry(hdev, func, data, destroy)) return 0;
/* Dequeue HCI command entry: * * - Lookup and cancel any entry that matches by function callback or data or * destroy callback.
*/ bool hci_cmd_sync_dequeue(struct hci_dev *hdev, hci_cmd_sync_work_func_t func, void *data, hci_cmd_sync_work_destroy_t destroy)
{ struct hci_cmd_sync_work_entry *entry; bool ret = false;
mutex_lock(&hdev->cmd_sync_work_lock); while ((entry = _hci_cmd_sync_lookup_entry(hdev, func, data,
destroy))) {
_hci_cmd_sync_cancel_entry(hdev, entry, -ECANCELED);
ret = true;
}
mutex_unlock(&hdev->cmd_sync_work_lock);
staticbool is_advertising_allowed(struct hci_dev *hdev, bool connectable)
{ /* If there is no connection we are OK to advertise. */ if (hci_conn_num(hdev, LE_LINK) == 0) returntrue;
/* Check le_states if there is any connection in peripheral role. */ if (hdev->conn_hash.le_num_peripheral > 0) { /* Peripheral connection state and non connectable mode * bit 20.
*/ if (!connectable && !(hdev->le_states[2] & 0x10)) returnfalse;
/* Peripheral connection state and connectable mode bit 38 * and scannable bit 21.
*/ if (connectable && (!(hdev->le_states[4] & 0x40) ||
!(hdev->le_states[2] & 0x20))) returnfalse;
}
/* Check le_states if there is any connection in central role. */ if (hci_conn_num(hdev, LE_LINK) != hdev->conn_hash.le_num_peripheral) { /* Central connection state and non connectable mode bit 18. */ if (!connectable && !(hdev->le_states[2] & 0x02)) returnfalse;
/* Central connection state and connectable mode bit 35 and * scannable 19.
*/ if (connectable && (!(hdev->le_states[4] & 0x08) ||
!(hdev->le_states[2] & 0x08))) returnfalse;
}
returntrue;
}
staticbool adv_use_rpa(struct hci_dev *hdev, uint32_t flags)
{ /* If privacy is not enabled don't use RPA */ if (!hci_dev_test_flag(hdev, HCI_PRIVACY)) returnfalse;
/* If basic privacy mode is enabled use RPA */ if (!hci_dev_test_flag(hdev, HCI_LIMITED_PRIVACY)) returntrue;
/* If limited privacy mode is enabled don't use RPA if we're * both discoverable and bondable.
*/ if ((flags & MGMT_ADV_FLAG_DISCOV) &&
hci_dev_test_flag(hdev, HCI_BONDABLE)) returnfalse;
/* We're neither bondable nor discoverable in the limited * privacy mode, therefore use RPA.
*/ returntrue;
}
staticint hci_set_random_addr_sync(struct hci_dev *hdev, bdaddr_t *rpa)
{ /* If a random_addr has been set we're advertising or initiating an LE * connection we can't go ahead and change the random address at this * time. This is because the eventual initiator address used for the * subsequently created connection will be undefined (some * controllers use the new address and others the one we had * when the operation started). * * In this kind of scenario skip the update and let the random * address be updated at the next cycle.
*/ if (bacmp(&hdev->random_addr, BDADDR_ANY) &&
(hci_dev_test_flag(hdev, HCI_LE_ADV) ||
hci_lookup_le_connect(hdev))) {
bt_dev_dbg(hdev, "Deferring random address update");
hci_dev_set_flag(hdev, HCI_RPA_EXPIRED); return 0;
}
int hci_update_random_address_sync(struct hci_dev *hdev, bool require_privacy, bool rpa, u8 *own_addr_type)
{ int err;
/* If privacy is enabled use a resolvable private address. If * current RPA has expired or there is something else than * the current RPA in use, then generate a new one.
*/ if (rpa) { /* If Controller supports LL Privacy use own address type is * 0x03
*/ if (ll_privacy_capable(hdev))
*own_addr_type = ADDR_LE_DEV_RANDOM_RESOLVED; else
*own_addr_type = ADDR_LE_DEV_RANDOM;
/* Check if RPA is valid */ if (rpa_valid(hdev)) return 0;
err = smp_generate_rpa(hdev, hdev->irk, &hdev->rpa); if (err < 0) {
bt_dev_err(hdev, "failed to generate new RPA"); return err;
}
err = hci_set_random_addr_sync(hdev, &hdev->rpa); if (err) return err;
return 0;
}
/* In case of required privacy without resolvable private address, * use an non-resolvable private address. This is useful for active * scanning and non-connectable advertising.
*/ if (require_privacy) {
bdaddr_t nrpa;
while (true) { /* The non-resolvable private address is generated * from random six bytes with the two most significant * bits cleared.
*/
get_random_bytes(&nrpa, 6);
nrpa.b[5] &= 0x3f;
/* The non-resolvable private address shall not be * equal to the public address.
*/ if (bacmp(&hdev->bdaddr, &nrpa)) break;
}
*own_addr_type = ADDR_LE_DEV_RANDOM;
return hci_set_random_addr_sync(hdev, &nrpa);
}
/* If forcing static address is in use or there is no public * address use the static address as random address (but skip * the HCI command if the current random address is already the * static one. * * In case BR/EDR has been disabled on a dual-mode controller * and a static address has been configured, then use that * address instead of the public BR/EDR address.
*/ if (hci_dev_test_flag(hdev, HCI_FORCE_STATIC_ADDR) ||
!bacmp(&hdev->bdaddr, BDADDR_ANY) ||
(!hci_dev_test_flag(hdev, HCI_BREDR_ENABLED) &&
bacmp(&hdev->static_addr, BDADDR_ANY))) {
*own_addr_type = ADDR_LE_DEV_RANDOM; if (bacmp(&hdev->static_addr, &hdev->random_addr)) return hci_set_random_addr_sync(hdev,
&hdev->static_addr); return 0;
}
/* Neither privacy nor static address is being used so use a * public address.
*/
*own_addr_type = ADDR_LE_DEV_PUBLIC;
/* If request specifies an instance that doesn't exist, fail */ if (instance > 0) {
adv = hci_find_adv_instance(hdev, instance); if (!adv) return -EINVAL;
/* If not enabled there is nothing to do */ if (!adv->enabled) return 0;
}
memset(data, 0, sizeof(data));
cp = (void *)data;
set = (void *)cp->data;
/* Instance 0x00 indicates all advertising instances will be disabled */
cp->num_of_sets = !!instance;
cp->enable = 0x00;
if (!instance) { /* Instance 0x00 doesn't have an adv_info, instead it uses * hdev->random_addr to track its address so whenever it needs * to be updated this also set the random address since * hdev->random_addr is shared with scan state machine.
*/
err = hci_set_random_addr_sync(hdev, random_addr); if (err) return err;
}
if (instance > 0) {
adv = hci_find_adv_instance(hdev, instance); if (!adv) return -EINVAL;
} else {
adv = NULL;
}
/* Updating parameters of an active instance will return a * Command Disallowed error, so we must first disable the * instance if it is active.
*/ if (adv) {
err = hci_disable_ext_adv_instance_sync(hdev, instance); if (err) return err;
}
flags = hci_adv_instance_flags(hdev, instance);
/* If the "connectable" instance flag was not set, then choose between * ADV_IND and ADV_NONCONN_IND based on the global connectable setting.
*/
connectable = (flags & MGMT_ADV_FLAG_CONNECTABLE) ||
mgmt_get_connectable(hdev);
if (!is_advertising_allowed(hdev, connectable)) return -EPERM;
/* Set require_privacy to true only when non-connectable * advertising is used and it is not periodic. * In that case it is fine to use a non-resolvable private address.
*/
require_privacy = !connectable && !(adv && adv->periodic);
/* If Own_Address_Type equals 0x02 or 0x03, the Peer_Address parameter * contains the peer’s Identity Address and the Peer_Address_Type * parameter contains the peer’s Identity Type (i.e., 0x00 or 0x01). * These parameters are used to locate the corresponding local IRK in * the resolving list; this IRK is used to generate their own address * used in the advertisement.
*/ if (own_addr_type == ADDR_LE_DEV_RANDOM_RESOLVED)
hci_copy_identity_address(hdev, &cp.peer_addr,
&cp.peer_addr_type);
if (flags & MGMT_ADV_FLAG_SEC_2M) {
cp.primary_phy = HCI_ADV_PHY_1M;
cp.secondary_phy = HCI_ADV_PHY_2M;
} elseif (flags & MGMT_ADV_FLAG_SEC_CODED) {
cp.primary_phy = HCI_ADV_PHY_CODED;
cp.secondary_phy = HCI_ADV_PHY_CODED;
} else { /* In all other cases use 1M */
cp.primary_phy = HCI_ADV_PHY_1M;
cp.secondary_phy = HCI_ADV_PHY_1M;
}
err = hci_set_ext_adv_params_sync(hdev, adv, &cp, &rp); if (err) return err;
/* Update adv data as tx power is known now */
err = hci_set_ext_adv_data_sync(hdev, cp.handle); if (err) return err;
if ((own_addr_type == ADDR_LE_DEV_RANDOM ||
own_addr_type == ADDR_LE_DEV_RANDOM_RESOLVED) &&
bacmp(&random_addr, BDADDR_ANY)) { /* Check if random address need to be updated */ if (adv) { if (!bacmp(&random_addr, &adv->random_addr)) return 0;
} else { if (!bacmp(&random_addr, &hdev->random_addr)) return 0;
}
if (instance > 0) {
adv = hci_find_adv_instance(hdev, instance); if (!adv) return -EINVAL; /* If already enabled there is nothing to do */ if (adv->enabled) return 0;
} else {
adv = NULL;
}
cp = (void *)data;
set = (void *)cp->data;
memset(cp, 0, sizeof(*cp));
cp->enable = 0x01;
cp->num_of_sets = 0x01;
memset(set, 0, sizeof(*set));
set->handle = adv ? adv->handle : instance;
/* Set duration per instance since controller is responsible for * scheduling it.
*/ if (adv && adv->timeout) {
u16 duration = adv->timeout * MSEC_PER_SEC;
/* Time = N * 10 ms */
set->duration = cpu_to_le16(duration / 10);
}
/* If periodic advertising already disabled there is nothing to do. */
adv = hci_find_adv_instance(hdev, instance); if (!adv || !adv->periodic_enabled) return 0;
/* If periodic advertising already enabled there is nothing to do. */
adv = hci_find_adv_instance(hdev, instance); if (adv && adv->periodic_enabled) return 0;
/* Checks if periodic advertising data contains a Basic Announcement and if it * does generates a Broadcast ID and add Broadcast Announcement.
*/ staticint hci_adv_bcast_annoucement(struct hci_dev *hdev, struct adv_info *adv)
{
u8 bid[3];
u8 ad[HCI_MAX_EXT_AD_LENGTH];
u8 len;
/* Skip if NULL adv as instance 0x00 is used for general purpose * advertising so it cannot used for the likes of Broadcast Announcement * as it can be overwritten at any point.
*/ if (!adv) return 0;
/* Check if PA data doesn't contains a Basic Audio Announcement then * there is nothing to do.
*/ if (!eir_get_service_data(adv->per_adv_data, adv->per_adv_data_len,
0x1851, NULL)) return 0;
/* Check if advertising data already has a Broadcast Announcement since * the process may want to control the Broadcast ID directly and in that * case the kernel shall no interfere.
*/ if (eir_get_service_data(adv->adv_data, adv->adv_data_len, 0x1852,
NULL)) return 0;
/* Generate Broadcast ID */
get_random_bytes(bid, sizeof(bid));
len = eir_append_service_data(ad, 0, 0x1852, bid, sizeof(bid));
memcpy(ad + len, adv->adv_data, adv->adv_data_len);
hci_set_adv_instance_data(hdev, adv->instance, len + adv->adv_data_len,
ad, 0, NULL);
if (instance) {
adv = hci_find_adv_instance(hdev, instance); if (adv) { if (sid != HCI_SID_INVALID && adv->sid != sid) { /* If the SID don't match attempt to find by * SID.
*/
adv = hci_find_adv_sid(hdev, sid); if (!adv) {
bt_dev_err(hdev, "Unable to find adv_info"); return -EINVAL;
}
}
/* Turn it into periodic advertising */
adv->periodic = true;
adv->per_adv_data_len = data_len; if (data)
memcpy(adv->per_adv_data, data, data_len);
adv->flags = flags;
} elseif (!adv) { /* Create an instance if that could not be found */
adv = hci_add_per_instance(hdev, instance, sid, flags,
data_len, data,
sync_interval,
sync_interval); if (IS_ERR(adv)) return PTR_ERR(adv);
adv->pending = false;
added = true;
}
}
/* If the "connectable" instance flag was not set, then choose between * ADV_IND and ADV_NONCONN_IND based on the global connectable setting.
*/
connectable = (flags & MGMT_ADV_FLAG_CONNECTABLE) ||
mgmt_get_connectable(hdev);
if (!is_advertising_allowed(hdev, connectable)) return -EINVAL;
status = hci_disable_advertising_sync(hdev); if (status) return status;
/* Clear the HCI_LE_ADV bit temporarily so that the * hci_update_random_address knows that it's safe to go ahead * and write a new random address. The flag will be set back on * as soon as the SET_ADV_ENABLE HCI command completes.
*/
hci_dev_clear_flag(hdev, HCI_LE_ADV);
/* Set require_privacy to true only when non-connectable * advertising is used. In that case it is fine to use a * non-resolvable private address.
*/
status = hci_update_random_address_sync(hdev, !connectable,
adv_use_rpa(hdev, flags),
&own_addr_type); if (status) return status;
if (hci_dev_test_flag(hdev, HCI_ADVERTISING) && !ext_adv_capable(hdev)) return -EPERM;
if (hdev->adv_instance_timeout) return -EBUSY;
adv = hci_find_adv_instance(hdev, instance); if (!adv) return -ENOENT;
/* A zero timeout means unlimited advertising. As long as there is * only one instance, duration should be ignored. We still set a timeout * in case further instances are being added later on. * * If the remaining lifetime of the instance is more than the duration * then the timeout corresponds to the duration, otherwise it will be * reduced to the remaining instance lifetime.
*/ if (adv->timeout == 0 || adv->duration <= adv->remaining_time)
timeout = adv->duration; else
timeout = adv->remaining_time;
/* The remaining time is being reduced unless the instance is being * advertised without time limit.
*/ if (adv->timeout)
adv->remaining_time = adv->remaining_time - timeout;
/* Only use work for scheduling instances with legacy advertising */ if (!ext_adv_capable(hdev)) {
hdev->adv_instance_timeout = timeout;
queue_delayed_work(hdev->req_workqueue,
&hdev->adv_instance_expire,
secs_to_jiffies(timeout));
}
/* If we're just re-scheduling the same instance again then do not * execute any HCI commands. This happens when a single instance is * being advertised.
*/ if (!force && hdev->cur_adv_instance == instance &&
hci_dev_test_flag(hdev, HCI_LE_ADV)) return 0;
hdev->cur_adv_instance = instance;
return hci_start_adv_sync(hdev, instance);
}
staticint hci_clear_adv_sets_sync(struct hci_dev *hdev, struct sock *sk)
{ int err;
if (!ext_adv_capable(hdev)) return 0;
/* Disable instance 0x00 to disable all instances */
err = hci_disable_ext_adv_instance_sync(hdev, 0x00); if (err) return err;
/* If we use extended advertising, instance has to be removed first. */ if (ext_adv_capable(hdev)) return hci_remove_ext_adv_instance_sync(hdev, instance, sk);
/* This is safe as long as there is no command send while the lock is * held.
*/
hci_dev_lock(hdev);
err = hci_remove_adv_instance(hdev, instance); if (!err)
mgmt_advertising_removed(sk, hdev, instance);
hci_dev_unlock(hdev);
return err;
}
/* For a single instance: * - force == true: The instance will be removed even when its remaining * lifetime is not zero. * - force == false: the instance will be deactivated but kept stored unless * the remaining lifetime is zero. * * For instance == 0x00: * - force == true: All instances will be removed regardless of their timeout * setting. * - force == false: Only instances that have a timeout will be removed.
*/ int hci_remove_advertising_sync(struct hci_dev *hdev, struct sock *sk,
u8 instance, bool force)
{ struct adv_info *next = NULL; int err;
/* Cancel any timeout concerning the removed instance(s). */ if (!instance || hdev->cur_adv_instance == instance)
cancel_adv_timeout(hdev);
/* Get the next instance to advertise BEFORE we remove * the current one. This can be the same instance again * if there is only one instance.
*/ if (hdev->cur_adv_instance == instance)
next = hci_get_next_instance(hdev, instance);
/* Return true if interleave_scan wasn't started until exiting this function, * otherwise, return false
*/ staticbool hci_update_interleaved_scan_sync(struct hci_dev *hdev)
{ /* Do interleaved scan only if all of the following are true: * - There is at least one ADV monitor * - At least one pending LE connection or one device to be scanned for * - Monitor offloading is not supported * If so, we should alternate between allowlist scan and one without * any filters to save power.
*/ bool use_interleaving = hci_is_adv_monitoring(hdev) &&
!(list_empty(&hdev->pend_le_conns) &&
list_empty(&hdev->pend_le_reports)) &&
hci_get_adv_monitor_offload_ext(hdev) ==
HCI_ADV_MONITOR_EXT_NONE; bool is_interleaving = is_interleave_scanning(hdev);
/* Ignore errors when removing from resolving list as that is likely * that the device was never added.
*/
hci_le_del_resolve_list_sync(hdev, &cp.bdaddr, cp.bdaddr_type);
err = __hci_cmd_sync_status(hdev, HCI_OP_LE_DEL_FROM_ACCEPT_LIST, sizeof(cp), &cp, HCI_CMD_TIMEOUT); if (err) {
bt_dev_err(hdev, "Unable to remove from allow list: %d", err); return err;
}
bt_dev_dbg(hdev, "Remove %pMR (0x%x) from allow list", &cp.bdaddr,
cp.bdaddr_type);
irk = hci_find_irk_by_addr(hdev, ¶ms->addr, params->addr_type); if (!irk) return 0;
/* Check if the IK has _not_ been programmed yet. */
entry = hci_bdaddr_list_lookup_with_irk(&hdev->le_resolv_list,
¶ms->addr,
params->addr_type); if (entry) return 0;
rcu_read_lock();
p = hci_pend_le_action_lookup(&hdev->pend_le_conns,
¶ms->addr, params->addr_type); if (!p)
p = hci_pend_le_action_lookup(&hdev->pend_le_reports,
¶ms->addr, params->addr_type); if (p)
WRITE_ONCE(p->privacy_mode, HCI_NETWORK_PRIVACY);
rcu_read_unlock();
if (!ll_privacy_capable(hdev) ||
!(params->flags & HCI_CONN_FLAG_ADDRESS_RESOLUTION)) return 0;
/* If device privacy mode has already been set there is nothing to do */ if (params->privacy_mode == HCI_DEVICE_PRIVACY) return 0;
/* Check if HCI_CONN_FLAG_DEVICE_PRIVACY has been set as it also * indicates that LL Privacy has been enabled and * HCI_OP_LE_SET_PRIVACY_MODE is supported.
*/ if (!(params->flags & HCI_CONN_FLAG_DEVICE_PRIVACY)) return 0;
irk = hci_find_irk_by_addr(hdev, ¶ms->addr, params->addr_type); if (!irk) return 0;
/* Adds connection to allow list if needed, if the device uses RPA (has IRK) * this attempts to program the device in the resolving list as well and * properly set the privacy mode.
*/ staticint hci_le_add_accept_list_sync(struct hci_dev *hdev, struct conn_params *params,
u8 *num_entries)
{ struct hci_cp_le_add_to_accept_list cp; int err;
/* During suspend, only wakeable devices can be in acceptlist */ if (hdev->suspended &&
!(params->flags & HCI_CONN_FLAG_REMOTE_WAKEUP)) {
hci_le_del_accept_list_sync(hdev, ¶ms->addr,
params->addr_type); return 0;
}
/* Select filter policy to accept all advertising */ if (*num_entries >= hdev->le_accept_list_size) return -ENOSPC;
/* Attempt to program the device in the resolving list first to avoid * having to rollback in case it fails since the resolving list is * dynamic it can probably be smaller than the accept list.
*/
err = hci_le_add_resolve_list_sync(hdev, params); if (err) {
bt_dev_err(hdev, "Unable to add to resolve list: %d", err); return err;
}
/* Set Privacy Mode */
err = hci_le_set_privacy_mode_sync(hdev, params); if (err) {
bt_dev_err(hdev, "Unable to set privacy mode: %d", err); return err;
}
/* Check if already in accept list */ if (hci_bdaddr_list_lookup(&hdev->le_accept_list, ¶ms->addr,
params->addr_type)) return 0;
err = __hci_cmd_sync_status(hdev, HCI_OP_LE_ADD_TO_ACCEPT_LIST, sizeof(cp), &cp, HCI_CMD_TIMEOUT); if (err) {
bt_dev_err(hdev, "Unable to add to allow list: %d", err); /* Rollback the device from the resolving list */
hci_le_del_resolve_list_sync(hdev, &cp.bdaddr, cp.bdaddr_type); return err;
}
bt_dev_dbg(hdev, "Add %pMR (0x%x) to allow list", &cp.bdaddr,
cp.bdaddr_type);
return 0;
}
/* This function disables/pause all advertising instances */ staticint hci_pause_advertising_sync(struct hci_dev *hdev)
{ int err; int old_state;
/* If controller is not advertising we are done. */ if (!hci_dev_test_flag(hdev, HCI_LE_ADV)) return 0;
/* If already been paused there is nothing to do. */ if (hdev->advertising_paused) return 0;
bt_dev_dbg(hdev, "Pausing directed advertising");
/* Stop directed advertising */
old_state = hci_dev_test_flag(hdev, HCI_ADVERTISING); if (old_state) { /* When discoverable timeout triggers, then just make sure * the limited discoverable flag is cleared. Even in the case * of a timeout triggered from general discoverable, it is * safe to unconditionally clear the flag.
*/
hci_dev_clear_flag(hdev, HCI_LIMITED_DISCOVERABLE);
hci_dev_clear_flag(hdev, HCI_DISCOVERABLE);
hdev->discov_timeout = 0;
}
/* Call to disable any advertisements active on the controller. * This will succeed even if no advertisements are configured.
*/
err = hci_disable_advertising_sync(hdev); if (err) return err;
/* If we are using software rotation, pause the loop */ if (!ext_adv_capable(hdev))
cancel_adv_timeout(hdev);
/* This function enables all user advertising instances */ staticint hci_resume_advertising_sync(struct hci_dev *hdev)
{ struct adv_info *adv, *tmp; int err;
/* If advertising has not been paused there is nothing to do. */ if (!hdev->advertising_paused) return 0;
if (ext_adv_capable(hdev)) { /* Call for each tracked instance to be re-enabled */
list_for_each_entry_safe(adv, tmp, &hdev->adv_instances, list) {
err = hci_enable_ext_advertising_sync(hdev,
adv->instance); if (!err) continue;
/* If the instance cannot be resumed remove it */
hci_remove_ext_adv_instance_sync(hdev, adv->instance,
NULL);
}
/* If current advertising instance is set to instance 0x00 * then we need to re-enable it.
*/ if (hci_dev_test_and_clear_flag(hdev, HCI_LE_ADV_0))
err = hci_enable_ext_advertising_sync(hdev, 0x00);
} else { /* Schedule for most recent instance to be restarted and begin * the software rotation loop
*/
err = hci_schedule_adv_instance_sync(hdev,
hdev->cur_adv_instance, true);
}
hdev->advertising_paused = false;
return err;
}
staticint hci_pause_addr_resolution(struct hci_dev *hdev)
{ int err;
if (!ll_privacy_capable(hdev)) return 0;
if (!hci_dev_test_flag(hdev, HCI_LL_RPA_RESOLUTION)) return 0;
/* Cannot disable addr resolution if scanning is enabled or * when initiating an LE connection.
*/ if (hci_dev_test_flag(hdev, HCI_LE_SCAN) ||
hci_lookup_le_connect(hdev)) {
bt_dev_err(hdev, "Command not allowed when scan/LE connect"); return -EPERM;
}
/* Cannot disable addr resolution if advertising is enabled. */
err = hci_pause_advertising_sync(hdev); if (err) {
bt_dev_err(hdev, "Pause advertising failed: %d", err); return err;
}
err = hci_le_set_addr_resolution_enable_sync(hdev, 0x00); if (err)
bt_dev_err(hdev, "Unable to disable Address Resolution: %d",
err);
/* Return if address resolution is disabled and RPA is not used. */ if (!err && scan_use_rpa(hdev)) return 0;
i = 0;
list_for_each_entry_rcu(params, list, action)
++i;
*n = i;
rcu_read_unlock();
p = kvcalloc(*n, sizeof(struct conn_params), GFP_KERNEL); if (!p) return NULL;
rcu_read_lock();
i = 0;
list_for_each_entry_rcu(params, list, action) { /* Racing adds are handled in next scan update */ if (i >= *n) break;
/* No hdev->lock, but: addr, addr_type are immutable. * privacy_mode is only written by us or in * hci_cc_le_set_privacy_mode that we wait for. * We should be idempotent so MGMT updating flags * while we are processing is OK.
*/
bacpy(&p[i].addr, ¶ms->addr);
p[i].addr_type = params->addr_type;
p[i].flags = READ_ONCE(params->flags);
p[i].privacy_mode = READ_ONCE(params->privacy_mode);
++i;
}
rcu_read_unlock();
*n = i; return p;
}
/* Clear LE Accept List */ staticint hci_le_clear_accept_list_sync(struct hci_dev *hdev)
{ if (!(hdev->commands[26] & 0x80)) return 0;
/* Device must not be scanning when updating the accept list. * * Update is done using the following sequence: * * ll_privacy_capable((Disable Advertising) -> Disable Resolving List) -> * Remove Devices From Accept List -> * (has IRK && ll_privacy_capable(Remove Devices From Resolving List))-> * Add Devices to Accept List -> * (has IRK && ll_privacy_capable(Remove Devices From Resolving List)) -> * ll_privacy_capable(Enable Resolving List -> (Enable Advertising)) -> * Enable Scanning * * In case of failure advertising shall be restored to its original state and * return would disable accept list since either accept or resolving list could * not be programmed. *
*/ static u8 hci_update_accept_list_sync(struct hci_dev *hdev)
{ struct conn_params *params; struct bdaddr_list *b, *t;
u8 num_entries = 0; bool pend_conn, pend_report;
u8 filter_policy;
size_t i, n; int err;
/* Pause advertising if resolving list can be used as controllers * cannot accept resolving list modifications while advertising.
*/ if (ll_privacy_capable(hdev)) {
err = hci_pause_advertising_sync(hdev); if (err) {
bt_dev_err(hdev, "pause advertising failed: %d", err); return 0x00;
}
}
/* Disable address resolution while reprogramming accept list since * devices that do have an IRK will be programmed in the resolving list * when LL Privacy is enabled.
*/
err = hci_le_set_addr_resolution_enable_sync(hdev, 0x00); if (err) {
bt_dev_err(hdev, "Unable to disable LL privacy: %d", err); goto done;
}
/* Force address filtering if PA Sync is in progress */ if (hci_dev_test_flag(hdev, HCI_PA_SYNC)) { struct hci_conn *conn;
conn = hci_conn_hash_lookup_create_pa_sync(hdev); if (conn) { struct conn_params pa;
/* Go through the current accept list programmed into the * controller one by one and check if that address is connected or is * still in the list of pending connections or list of devices to * report. If not present in either list, then remove it from * the controller.
*/
list_for_each_entry_safe(b, t, &hdev->le_accept_list, list) { if (hci_conn_hash_lookup_le(hdev, &b->bdaddr, b->bdaddr_type)) continue;
/* Pointers not dereferenced, no locks needed */
pend_conn = hci_pend_le_action_lookup(&hdev->pend_le_conns,
&b->bdaddr,
b->bdaddr_type);
pend_report = hci_pend_le_action_lookup(&hdev->pend_le_reports,
&b->bdaddr,
b->bdaddr_type);
/* If the device is not likely to connect or report, * remove it from the acceptlist.
*/ if (!pend_conn && !pend_report) {
hci_le_del_accept_list_sync(hdev, &b->bdaddr,
b->bdaddr_type); continue;
}
num_entries++;
}
/* Since all no longer valid accept list entries have been * removed, walk through the list of pending connections * and ensure that any new device gets programmed into * the controller. * * If the list of the devices is larger than the list of * available accept list entries in the controller, then * just abort and return filer policy value to not use the * accept list. * * The list and params may be mutated while we wait for events, * so make a copy and iterate it.
*/
for (i = 0; i < n; ++i) {
err = hci_le_add_accept_list_sync(hdev, ¶ms[i],
&num_entries); if (err) {
kvfree(params); goto done;
}
}
kvfree(params);
/* After adding all new pending connections, walk through * the list of pending reports and also add these to the * accept list if there is still space. Abort if space runs out.
*/
for (i = 0; i < n; ++i) {
err = hci_le_add_accept_list_sync(hdev, ¶ms[i],
&num_entries); if (err) {
kvfree(params); goto done;
}
}
kvfree(params);
/* Use the allowlist unless the following conditions are all true: * - We are not currently suspending * - There are 1 or more ADV monitors registered and it's not offloaded * - Interleaved scanning is not currently using the allowlist
*/ if (!idr_is_empty(&hdev->adv_monitors_idr) && !hdev->suspended &&
hci_get_adv_monitor_offload_ext(hdev) == HCI_ADV_MONITOR_EXT_NONE &&
hdev->interleave_scan_state != INTERLEAVE_SCAN_ALLOWLIST)
err = -EINVAL;
done:
filter_policy = err ? 0x00 : 0x01;
/* Enable address resolution when LL Privacy is enabled. */
err = hci_le_set_addr_resolution_enable_sync(hdev, 0x01); if (err)
bt_dev_err(hdev, "Unable to enable LL privacy: %d", err);
/* Resume advertising if it was paused */ if (ll_privacy_capable(hdev))
hci_resume_advertising_sync(hdev);
/* Select filter policy to use accept list */ return filter_policy;
}
/* Check if PA Sync is in progress then select the PHY based on the * hci_conn.iso_qos.
*/ if (hci_dev_test_flag(hdev, HCI_PA_SYNC)) { struct hci_cp_le_add_to_accept_list *sent;
sent = hci_sent_cmd_data(hdev, HCI_OP_LE_ADD_TO_ACCEPT_LIST); if (sent) { struct hci_conn *conn;
/* Set require_privacy to false since no SCAN_REQ are send * during passive scanning. Not using an non-resolvable address * here is important so that peer devices using direct * advertising with our address will be correctly reported * by the controller.
*/ if (hci_update_random_address_sync(hdev, false, scan_use_rpa(hdev),
&own_addr_type)) return 0;
if (hdev->enable_advmon_interleave_scan &&
hci_update_interleaved_scan_sync(hdev)) return 0;
bt_dev_dbg(hdev, "interleave state %d", hdev->interleave_scan_state);
/* Adding or removing entries from the accept list must * happen before enabling scanning. The controller does * not allow accept list modification while scanning.
*/
filter_policy = hci_update_accept_list_sync(hdev);
/* If suspended and filter_policy set to 0x00 (no acceptlist) then * passive scanning cannot be started since that would require the host * to be woken up to process the reports.
*/ if (hdev->suspended && !filter_policy) { /* Check if accept list is empty then there is no need to scan * while suspended.
*/ if (list_empty(&hdev->le_accept_list)) return 0;
/* If there are devices is the accept_list that means some * devices could not be programmed which in non-suspended case * means filter_policy needs to be set to 0x00 so the host needs * to filter, but since this is treating suspended case we * can ignore device needing host to filter to allow devices in * the acceptlist to be able to wakeup the system.
*/
filter_policy = 0x01;
}
/* When the controller is using random resolvable addresses and * with that having LE privacy enabled, then controllers with * Extended Scanner Filter Policies support can now enable support * for handling directed advertising. * * So instead of using filter polices 0x00 (no acceptlist) * and 0x01 (acceptlist enabled) use the new filter policies * 0x02 (no acceptlist) and 0x03 (acceptlist enabled).
*/ if (hci_dev_test_flag(hdev, HCI_PRIVACY) &&
(hdev->le_features[0] & HCI_LE_EXT_SCAN_POLICY))
filter_policy |= 0x02;
/* Disable duplicates filter when scanning for advertisement * monitor for the following reasons. * * For HW pattern filtering (ex. MSFT), Realtek and Qualcomm * controllers ignore RSSI_Sampling_Period when the duplicates * filter is enabled. * * For SW pattern filtering, when we're not doing interleaved * scanning, it is necessary to disable duplicates filter, * otherwise hosts can only receive one advertisement and it's * impossible to know if a peer is still in range.
*/
filter_dups = LE_SCAN_FILTER_DUP_DISABLE;
} else {
window = hdev->le_scan_window;
interval = hdev->le_scan_interval;
}
/* Disable all filtering for Mesh */ if (hci_dev_test_flag(hdev, HCI_MESH)) {
filter_policy = 0;
filter_dups = LE_SCAN_FILTER_DUP_DISABLE;
}
bt_dev_dbg(hdev, "LE passive scan with acceptlist = %d", filter_policy);
/* This function controls the passive scanning based on hdev->pend_le_conns * list. If there are pending LE connection we start the background scanning, * otherwise we stop it in the following sequence: * * If there are devices to scan: * * Disable Scanning -> Update Accept List -> * ll_privacy_capable((Disable Advertising) -> Disable Resolving List -> * Update Resolving List -> Enable Resolving List -> (Enable Advertising)) -> * Enable Scanning * * Otherwise: * * Disable Scanning
*/ int hci_update_passive_scan_sync(struct hci_dev *hdev)
{ int err;
/* No point in doing scanning if LE support hasn't been enabled */ if (!hci_dev_test_flag(hdev, HCI_LE_ENABLED)) return 0;
/* If discovery is active don't interfere with it */ if (hdev->discovery.state != DISCOVERY_STOPPED) return 0;
/* Reset RSSI and UUID filters when starting background scanning * since these filters are meant for service discovery only. * * The Start Discovery and Start Service Discovery operations * ensure to set proper values for RSSI threshold and UUID * filter list. So it is safe to just reset them here.
*/
hci_discovery_filter_clear(hdev);
bt_dev_dbg(hdev, "ADV monitoring is %s",
hci_is_adv_monitoring(hdev) ? "on" : "off");
if (!hci_dev_test_flag(hdev, HCI_MESH) &&
list_empty(&hdev->pend_le_conns) &&
list_empty(&hdev->pend_le_reports) &&
!hci_is_adv_monitoring(hdev) &&
!hci_dev_test_flag(hdev, HCI_PA_SYNC)) { /* If there is no pending LE connections or devices * to be scanned for or no ADV monitors, we should stop the * background scanning.
*/
bt_dev_dbg(hdev, "stopping background scanning");
err = hci_scan_disable_sync(hdev); if (err)
bt_dev_err(hdev, "stop background scanning failed: %d",
err);
} else { /* If there is at least one pending LE connection, we should * keep the background scan running.
*/
/* If controller is connecting, we should not start scanning * since some controllers are not able to scan and connect at * the same time.
*/ if (hci_lookup_le_connect(hdev)) return 0;
int hci_update_passive_scan(struct hci_dev *hdev)
{ /* Only queue if it would have any effect */ if (!test_bit(HCI_UP, &hdev->flags) ||
test_bit(HCI_INIT, &hdev->flags) ||
hci_dev_test_flag(hdev, HCI_SETUP) ||
hci_dev_test_flag(hdev, HCI_CONFIG) ||
hci_dev_test_flag(hdev, HCI_AUTO_OFF) ||
hci_dev_test_flag(hdev, HCI_UNREGISTER)) return 0;
int hci_write_le_host_supported_sync(struct hci_dev *hdev, u8 le, u8 simul)
{ struct hci_cp_write_le_host_supported cp;
if (!hci_dev_test_flag(hdev, HCI_LE_ENABLED) ||
!lmp_bredr_capable(hdev)) return 0;
/* Check first if we already have the right host state * (host features set)
*/ if (le == lmp_host_le_capable(hdev) &&
simul == lmp_host_le_br_capable(hdev)) return 0;
if (!hci_dev_test_flag(hdev, HCI_LE_ENABLED)) return 0;
/* If RPA Resolution has not been enable yet it means the * resolving list is empty and we should attempt to program the * local IRK in order to support using own_addr_type * ADDR_LE_DEV_RANDOM_RESOLVED (0x03).
*/ if (!hci_dev_test_flag(hdev, HCI_LL_RPA_RESOLUTION)) {
hci_le_add_resolve_list_sync(hdev, NULL);
hci_le_set_addr_resolution_enable_sync(hdev, 0x01);
}
/* Make sure the controller has a good default for * advertising data. This also applies to the case * where BR/EDR was toggled during the AUTO_OFF phase.
*/ if (hci_dev_test_flag(hdev, HCI_ADVERTISING) &&
list_empty(&hdev->adv_instances)) { if (ext_adv_capable(hdev)) {
err = hci_setup_ext_adv_instance_sync(hdev, 0x00); if (!err)
hci_update_scan_rsp_data_sync(hdev, 0x00);
} else {
err = hci_update_adv_data_sync(hdev, 0x00); if (!err)
hci_update_scan_rsp_data_sync(hdev, 0x00);
}
if (hci_dev_test_flag(hdev, HCI_ADVERTISING))
hci_enable_advertising_sync(hdev);
}
/* Call for each tracked instance to be scheduled */
list_for_each_entry_safe(adv, tmp, &hdev->adv_instances, list)
hci_schedule_adv_instance_sync(hdev, adv->instance, true);
/* This function perform powered update HCI command sequence after the HCI init * sequence which end up resetting all states, the sequence is as follows: * * HCI_SSP_ENABLED(Enable SSP) * HCI_LE_ENABLED(Enable LE) * HCI_LE_ENABLED(ll_privacy_capable(Add local IRK to Resolving List) -> * Update adv data) * Enable Authentication * lmp_bredr_capable(Set Fast Connectable -> Set Scan Type -> Set Class -> * Set Name -> Set EIR) * HCI_FORCE_STATIC_ADDR | BDADDR_ANY && !HCI_BREDR_ENABLED (Set Static Address)
*/ int hci_powered_update_sync(struct hci_dev *hdev)
{ int err;
/* Register the available SMP channels (BR/EDR and LE) only when * successfully powering on the controller. This late * registration is required so that LE SMP can clearly decide if * the public address or static address is used.
*/
smp_register(hdev);
err = hci_write_ssp_mode_sync(hdev, 0x01); if (err) return err;
err = hci_write_le_host_supported_sync(hdev, 0x01, 0x00); if (err) return err;
err = hci_powered_update_adv_sync(hdev); if (err) return err;
err = hci_write_auth_enable_sync(hdev); if (err) return err;
if (lmp_bredr_capable(hdev)) { if (hci_dev_test_flag(hdev, HCI_FAST_CONNECTABLE))
hci_write_fast_connectable_sync(hdev, true); else
hci_write_fast_connectable_sync(hdev, false);
hci_update_scan_sync(hdev);
hci_update_class_sync(hdev);
hci_update_name_sync(hdev, hdev->dev_name);
hci_update_eir_sync(hdev);
}
/* If forcing static address is in use or there is no public * address use the static address as random address (but skip * the HCI command if the current random address is already the * static one. * * In case BR/EDR has been disabled on a dual-mode controller * and a static address has been configured, then use that * address instead of the public BR/EDR address.
*/ if (hci_dev_test_flag(hdev, HCI_FORCE_STATIC_ADDR) ||
(!bacmp(&hdev->bdaddr, BDADDR_ANY) &&
!hci_dev_test_flag(hdev, HCI_BREDR_ENABLED))) { if (bacmp(&hdev->static_addr, BDADDR_ANY)) return hci_set_random_addr_sync(hdev,
&hdev->static_addr);
}
return 0;
}
/** * hci_dev_get_bd_addr_from_property - Get the Bluetooth Device Address * (BD_ADDR) for a HCI device from * a firmware node property. * @hdev: The HCI device * * Search the firmware node for 'local-bd-address'. * * All-zero BD addresses are rejected, because those could be properties * that exist in the firmware tables, but were not updated by the firmware. For * example, the DTS could define 'local-bd-address', with zero BD addresses.
*/ staticvoid hci_dev_get_bd_addr_from_property(struct hci_dev *hdev)
{ struct fwnode_handle *fwnode = dev_fwnode(hdev->dev.parent);
bdaddr_t ba; int ret;
ret = fwnode_property_read_u8_array(fwnode, "local-bd-address",
(u8 *)&ba, sizeof(ba)); if (ret < 0 || !bacmp(&ba, BDADDR_ANY)) return;
if (hci_test_quirk(hdev, HCI_QUIRK_BDADDR_PROPERTY_BROKEN))
baswap(&hdev->public_addr, &ba); else
bacpy(&hdev->public_addr, &ba);
}
struct hci_init_stage { int (*func)(struct hci_dev *hdev);
};
/* Run init stage NULL terminated function table */ staticint hci_init_stage_sync(struct hci_dev *hdev, conststruct hci_init_stage *stage)
{
size_t i;
for (i = 0; stage[i].func; i++) { int err;
err = stage[i].func(hdev); if (err) return err;
}
return 0;
}
/* Read Local Version */ staticint hci_read_local_version_sync(struct hci_dev *hdev)
{ return __hci_cmd_sync_status(hdev, HCI_OP_READ_LOCAL_VERSION,
0, NULL, HCI_CMD_TIMEOUT);
}
/* Read Local Commands */ staticint hci_read_local_cmds_sync(struct hci_dev *hdev)
{ /* All Bluetooth 1.2 and later controllers should support the * HCI command for reading the local supported commands. * * Unfortunately some controllers indicate Bluetooth 1.2 support, * but do not have support for this command. If that is the case, * the driver can quirk the behavior and skip reading the local * supported commands.
*/ if (hdev->hci_ver > BLUETOOTH_VER_1_1 &&
!hci_test_quirk(hdev, HCI_QUIRK_BROKEN_LOCAL_COMMANDS)) return __hci_cmd_sync_status(hdev, HCI_OP_READ_LOCAL_COMMANDS,
0, NULL, HCI_CMD_TIMEOUT);
return 0;
}
staticint hci_init1_sync(struct hci_dev *hdev)
{ int err;
bt_dev_dbg(hdev, "");
/* Reset */ if (!hci_test_quirk(hdev, HCI_QUIRK_RESET_ON_CLOSE)) {
err = hci_reset_sync(hdev); if (err) return err;
}
staticint hci_clear_event_filter_sync(struct hci_dev *hdev)
{ if (!hci_dev_test_flag(hdev, HCI_EVENT_FILTER_CONFIGURED)) return 0;
/* In theory the state machine should not reach here unless * a hci_set_event_filter_sync() call succeeds, but we do * the check both for parity and as a future reminder.
*/ if (hci_test_quirk(hdev, HCI_QUIRK_BROKEN_FILTER_CLEAR_ALL)) return 0;
if (!lmp_ssp_capable(hdev) || !hci_dev_test_flag(hdev, HCI_SSP_ENABLED)) return 0;
/* When SSP is available, then the host features page * should also be available as well. However some * controllers list the max_page as 0 as long as SSP * has not been enabled. To achieve proper debugging * output, force the minimum max_page to 1 at least.
*/
hdev->max_page = 0x01;
if (!lmp_inq_rssi_capable(hdev) &&
!hci_test_quirk(hdev, HCI_QUIRK_FIXUP_INQUIRY_MODE)) return 0;
/* If Extended Inquiry Result events are supported, then * they are clearly preferred over Inquiry Result with RSSI * events.
*/
mode = lmp_ext_inq_capable(hdev) ? 0x02 : 0x01;
staticint hci_init2_sync(struct hci_dev *hdev)
{ int err;
bt_dev_dbg(hdev, "");
err = hci_init_stage_sync(hdev, hci_init2); if (err) return err;
if (lmp_bredr_capable(hdev)) {
err = hci_init_stage_sync(hdev, br_init2); if (err) return err;
} else {
hci_dev_clear_flag(hdev, HCI_BREDR_ENABLED);
}
if (lmp_le_capable(hdev)) {
err = hci_init_stage_sync(hdev, le_init2); if (err) return err; /* LE-only controllers have LE implicitly enabled */ if (!lmp_bredr_capable(hdev))
hci_dev_set_flag(hdev, HCI_LE_ENABLED);
}
return 0;
}
staticint hci_set_event_mask_sync(struct hci_dev *hdev)
{ /* The second byte is 0xff instead of 0x9f (two reserved bits * disabled) since a Broadcom 1.2 dongle doesn't respond to the * command otherwise.
*/
u8 events[8] = { 0xff, 0xff, 0xfb, 0xff, 0x00, 0x00, 0x00, 0x00 };
/* CSR 1.1 dongles does not accept any bitfield so don't try to set * any event mask for pre 1.2 devices.
*/ if (hdev->hci_ver < BLUETOOTH_VER_1_2) return 0;
/* Don't set Disconnect Complete and mode change when * suspended as that would wakeup the host when disconnecting * due to suspend.
*/ if (hdev->suspended) {
events[0] &= 0xef;
events[2] &= 0xf7;
}
} else { /* Use a different default for LE-only devices */
memset(events, 0, sizeof(events));
events[1] |= 0x20; /* Command Complete */
events[1] |= 0x40; /* Command Status */
events[1] |= 0x80; /* Hardware Error */
/* If the controller supports the Disconnect command, enable * the corresponding event. In addition enable packet flow * control related events.
*/ if (hdev->commands[0] & 0x20) { /* Don't set Disconnect Complete when suspended as that * would wakeup the host when disconnecting due to * suspend.
*/ if (!hdev->suspended)
events[0] |= 0x10; /* Disconnection Complete */
events[2] |= 0x04; /* Number of Completed Packets */
events[3] |= 0x02; /* Data Buffer Overflow */
}
/* If the controller supports the Read Remote Version * Information command, enable the corresponding event.
*/ if (hdev->commands[2] & 0x80)
events[1] |= 0x08; /* Read Remote Version Information * Complete
*/
if (lmp_rswitch_capable(hdev))
link_policy |= HCI_LP_RSWITCH; if (lmp_hold_capable(hdev))
link_policy |= HCI_LP_HOLD; if (lmp_sniff_capable(hdev))
link_policy |= HCI_LP_SNIFF; if (lmp_park_capable(hdev))
link_policy |= HCI_LP_PARK;
staticint hci_read_page_scan_type_sync(struct hci_dev *hdev)
{ /* Some older Broadcom based Bluetooth 1.2 controllers do not * support the Read Page Scan Type command. Check support for * this command in the bit mask of supported commands.
*/ if (!(hdev->commands[13] & 0x01) ||
hci_test_quirk(hdev, HCI_QUIRK_BROKEN_READ_PAGE_SCAN_TYPE)) return 0;
if (hdev->le_features[0] & HCI_LE_ENCRYPTION)
events[0] |= 0x10; /* LE Long Term Key Request */
/* If controller supports the Connection Parameters Request * Link Layer Procedure, enable the corresponding event.
*/ if (hdev->le_features[0] & HCI_LE_CONN_PARAM_REQ_PROC) /* LE Remote Connection Parameter Request */
events[0] |= 0x20;
/* If the controller supports the Data Length Extension * feature, enable the corresponding event.
*/ if (hdev->le_features[0] & HCI_LE_DATA_LEN_EXT)
events[0] |= 0x40; /* LE Data Length Change */
/* If the controller supports LL Privacy feature or LE Extended Adv, * enable the corresponding event.
*/ if (use_enhanced_conn_complete(hdev))
events[1] |= 0x02; /* LE Enhanced Connection Complete */
/* Mark Device Privacy if Privacy Mode is supported */ if (privacy_mode_capable(hdev))
hdev->conn_flags |= HCI_CONN_FLAG_DEVICE_PRIVACY;
/* Mark Address Resolution if LL Privacy is supported */ if (ll_privacy_capable(hdev))
hdev->conn_flags |= HCI_CONN_FLAG_ADDRESS_RESOLUTION;
/* If the controller supports Extended Scanner Filter * Policies, enable the corresponding event.
*/ if (hdev->le_features[0] & HCI_LE_EXT_SCAN_POLICY)
events[1] |= 0x04; /* LE Direct Advertising Report */
/* If the controller supports Channel Selection Algorithm #2 * feature, enable the corresponding event.
*/ if (hdev->le_features[1] & HCI_LE_CHAN_SEL_ALG2)
events[2] |= 0x08; /* LE Channel Selection Algorithm */
/* If the controller supports the LE Set Scan Enable command, * enable the corresponding advertising report event.
*/ if (hdev->commands[26] & 0x08)
events[0] |= 0x02; /* LE Advertising Report */
/* If the controller supports the LE Create Connection * command, enable the corresponding event.
*/ if (hdev->commands[26] & 0x10)
events[0] |= 0x01; /* LE Connection Complete */
/* If the controller supports the LE Connection Update * command, enable the corresponding event.
*/ if (hdev->commands[27] & 0x04)
events[0] |= 0x04; /* LE Connection Update Complete */
/* If the controller supports the LE Read Remote Used Features * command, enable the corresponding event.
*/ if (hdev->commands[27] & 0x20) /* LE Read Remote Used Features Complete */
events[0] |= 0x08;
/* If the controller supports the LE Read Local P-256 * Public Key command, enable the corresponding event.
*/ if (hdev->commands[34] & 0x02) /* LE Read Local P-256 Public Key Complete */
events[0] |= 0x80;
/* If the controller supports the LE Generate DHKey * command, enable the corresponding event.
*/ if (hdev->commands[34] & 0x04)
events[1] |= 0x01; /* LE Generate DHKey Complete */
/* If the controller supports the LE Set Default PHY or * LE Set PHY commands, enable the corresponding event.
*/ if (hdev->commands[35] & (0x20 | 0x40))
events[1] |= 0x08; /* LE PHY Update Complete */
/* If the controller supports LE Set Extended Scan Parameters * and LE Set Extended Scan Enable commands, enable the * corresponding event.
*/ if (use_ext_scan(hdev))
events[1] |= 0x10; /* LE Extended Advertising Report */
/* If the controller supports the LE Extended Advertising * command, enable the corresponding event.
*/ if (ext_adv_capable(hdev))
events[2] |= 0x02; /* LE Advertising Set Terminated */
if (cis_capable(hdev)) {
events[3] |= 0x01; /* LE CIS Established */ if (cis_peripheral_capable(hdev))
events[3] |= 0x02; /* LE CIS Request */
}
if (bis_capable(hdev)) {
events[1] |= 0x20; /* LE PA Report */
events[1] |= 0x40; /* LE PA Sync Established */
events[3] |= 0x04; /* LE Create BIG Complete */
events[3] |= 0x08; /* LE Terminate BIG Complete */
events[3] |= 0x10; /* LE BIG Sync Established */
events[3] |= 0x20; /* LE BIG Sync Loss */
events[4] |= 0x02; /* LE BIG Info Advertising Report */
}
/* Read LE Advertising Channel TX Power */ staticint hci_le_read_adv_tx_power_sync(struct hci_dev *hdev)
{ if ((hdev->commands[25] & 0x40) && !ext_adv_capable(hdev)) { /* HCI TS spec forbids mixing of legacy and extended * advertising commands wherein READ_ADV_TX_POWER is * also included. So do not call it if extended adv * is supported otherwise controller will return * COMMAND_DISALLOWED for extended commands.
*/ return __hci_cmd_sync_status(hdev,
HCI_OP_LE_READ_ADV_TX_POWER,
0, NULL, HCI_CMD_TIMEOUT);
}
return 0;
}
/* Read LE Min/Max Tx Power*/ staticint hci_le_read_tx_power_sync(struct hci_dev *hdev)
{ if (!(hdev->commands[38] & 0x80) ||
hci_test_quirk(hdev, HCI_QUIRK_BROKEN_READ_TRANSMIT_POWER)) return 0;
/* Read LE Maximum Data Length */ staticint hci_le_read_max_data_len_sync(struct hci_dev *hdev)
{ if (!(hdev->le_features[0] & HCI_LE_DATA_LEN_EXT)) return 0;
/* Read LE Number of Supported Advertising Sets */ staticint hci_le_read_num_support_adv_sets_sync(struct hci_dev *hdev)
{ if (!ext_adv_capable(hdev)) return 0;
/* Some Broadcom based Bluetooth controllers do not support the * Delete Stored Link Key command. They are clearly indicating its * absence in the bit mask of supported commands. * * Check the supported commands and only if the command is marked * as supported send it. If not supported assume that the controller * does not have actual support for stored link keys which makes this * command redundant anyway. * * Some controllers indicate that they support handling deleting * stored link keys, but they don't. The quirk lets a driver * just disable this command.
*/ if (!(hdev->commands[6] & 0x80) ||
hci_test_quirk(hdev, HCI_QUIRK_BROKEN_STORED_LINK_KEY)) return 0;
/* Some Broadcom based controllers indicate support for Set Event * Mask Page 2 command, but then actually do not support it. Since * the default value is all bits set to zero, the command is only * required if the event mask has to be changed. In case no change * to the event mask is needed, skip this command.
*/ if (!changed) return 0;
/* Read local codec list if the HCI command is supported */ staticint hci_read_local_codecs_sync(struct hci_dev *hdev)
{ if (hdev->commands[45] & 0x04)
hci_read_supported_codecs_v2(hdev); elseif (hdev->commands[29] & 0x20)
hci_read_supported_codecs(hdev);
return 0;
}
/* Read local pairing options if the HCI command is supported */ staticint hci_read_local_pairing_opts_sync(struct hci_dev *hdev)
{ if (!(hdev->commands[41] & 0x08)) return 0;
/* Get MWS transport configuration if the HCI command is supported */ staticint hci_get_mws_transport_config_sync(struct hci_dev *hdev)
{ if (!mws_transport_config_capable(hdev)) return 0;
/* Set erroneous data reporting if supported to the wideband speech * setting value
*/ staticint hci_set_err_data_report_sync(struct hci_dev *hdev)
{ struct hci_cp_write_def_err_data_reporting cp; bool enabled = hci_dev_test_flag(hdev, HCI_WIDEBAND_SPEECH_ENABLED);
/* Set Suggested Default Data Length to maximum if supported */ staticint hci_le_set_write_def_data_len_sync(struct hci_dev *hdev)
{ struct hci_cp_le_write_def_data_len cp;
if (!(hdev->le_features[0] & HCI_LE_DATA_LEN_EXT)) return 0;
/* Set Default PHY parameters if command is supported, enables all supported * PHYs according to the LE Features bits.
*/ staticint hci_le_set_default_phy_sync(struct hci_dev *hdev)
{ struct hci_cp_le_set_default_phy cp;
if (!(hdev->commands[35] & 0x20)) { /* If the command is not supported it means only 1M PHY is * supported.
*/
hdev->le_tx_def_phys = HCI_LE_SET_PHY_1M;
hdev->le_rx_def_phys = HCI_LE_SET_PHY_1M; return 0;
}
staticint hci_init4_sync(struct hci_dev *hdev)
{ int err;
bt_dev_dbg(hdev, "");
err = hci_init_stage_sync(hdev, hci_init4); if (err) return err;
if (lmp_le_capable(hdev)) return hci_init_stage_sync(hdev, le_init4);
return 0;
}
staticint hci_init_sync(struct hci_dev *hdev)
{ int err;
err = hci_init1_sync(hdev); if (err < 0) return err;
if (hci_dev_test_flag(hdev, HCI_SETUP))
hci_debugfs_create_basic(hdev);
err = hci_init2_sync(hdev); if (err < 0) return err;
err = hci_init3_sync(hdev); if (err < 0) return err;
err = hci_init4_sync(hdev); if (err < 0) return err;
/* This function is only called when the controller is actually in * configured state. When the controller is marked as unconfigured, * this initialization procedure is not run. * * It means that it is possible that a controller runs through its * setup phase and then discovers missing settings. If that is the * case, then this function will not be called. It then will only * be called during the config phase. * * So only when in setup phase or config phase, create the debugfs * entries and register the SMP channels.
*/ if (!hci_dev_test_flag(hdev, HCI_SETUP) &&
!hci_dev_test_flag(hdev, HCI_CONFIG)) return 0;
if (hci_dev_test_and_set_flag(hdev, HCI_DEBUGFS_CREATED)) return 0;
hci_debugfs_create_common(hdev);
if (lmp_bredr_capable(hdev))
hci_debugfs_create_bredr(hdev);
if (lmp_le_capable(hdev))
hci_debugfs_create_le(hdev);
staticconststruct { unsignedlong quirk; constchar *desc;
} hci_broken_table[] = {
HCI_QUIRK_BROKEN(LOCAL_COMMANDS, "HCI Read Local Supported Commands not supported"),
HCI_QUIRK_BROKEN(STORED_LINK_KEY, "HCI Delete Stored Link Key command is advertised, " "but not supported."),
HCI_QUIRK_BROKEN(ERR_DATA_REPORTING, "HCI Read Default Erroneous Data Reporting command is " "advertised, but not supported."),
HCI_QUIRK_BROKEN(READ_TRANSMIT_POWER, "HCI Read Transmit Power Level command is advertised, " "but not supported."),
HCI_QUIRK_BROKEN(FILTER_CLEAR_ALL, "HCI Set Event Filter command not supported."),
HCI_QUIRK_BROKEN(ENHANCED_SETUP_SYNC_CONN, "HCI Enhanced Setup Synchronous Connection command is " "advertised, but not supported."),
HCI_QUIRK_BROKEN(SET_RPA_TIMEOUT, "HCI LE Set Random Private Address Timeout command is " "advertised, but not supported."),
HCI_QUIRK_BROKEN(EXT_CREATE_CONN, "HCI LE Extended Create Connection command is " "advertised, but not supported."),
HCI_QUIRK_BROKEN(WRITE_AUTH_PAYLOAD_TIMEOUT, "HCI WRITE AUTH PAYLOAD TIMEOUT command leads " "to unexpected SMP errors when pairing " "and will not be used."),
HCI_QUIRK_BROKEN(LE_CODED, "HCI LE Coded PHY feature bit is set, " "but its usage is not supported.")
};
/* This function handles hdev setup stage: * * Calls hdev->setup * Setup address if HCI_QUIRK_USE_BDADDR_PROPERTY is set.
*/ staticint hci_dev_setup_sync(struct hci_dev *hdev)
{ int ret = 0; bool invalid_bdaddr;
size_t i;
if (!hci_dev_test_flag(hdev, HCI_SETUP) &&
!hci_test_quirk(hdev, HCI_QUIRK_NON_PERSISTENT_SETUP)) return 0;
bt_dev_dbg(hdev, "");
hci_sock_dev_event(hdev, HCI_DEV_SETUP);
if (hdev->setup)
ret = hdev->setup(hdev);
for (i = 0; i < ARRAY_SIZE(hci_broken_table); i++) { if (hci_test_quirk(hdev, hci_broken_table[i].quirk))
bt_dev_warn(hdev, "%s", hci_broken_table[i].desc);
}
/* The transport driver can set the quirk to mark the * BD_ADDR invalid before creating the HCI device or in * its setup callback.
*/
invalid_bdaddr = hci_test_quirk(hdev, HCI_QUIRK_INVALID_BDADDR) ||
hci_test_quirk(hdev, HCI_QUIRK_USE_BDADDR_PROPERTY); if (!ret) { if (hci_test_quirk(hdev, HCI_QUIRK_USE_BDADDR_PROPERTY) &&
!bacmp(&hdev->public_addr, BDADDR_ANY))
hci_dev_get_bd_addr_from_property(hdev);
if (invalid_bdaddr && bacmp(&hdev->public_addr, BDADDR_ANY) &&
hdev->set_bdaddr) {
ret = hdev->set_bdaddr(hdev, &hdev->public_addr); if (!ret)
invalid_bdaddr = false;
}
}
/* The transport driver can set these quirks before * creating the HCI device or in its setup callback. * * For the invalid BD_ADDR quirk it is possible that * it becomes a valid address if the bootloader does * provide it (see above). * * In case any of them is set, the controller has to * start up as unconfigured.
*/ if (hci_test_quirk(hdev, HCI_QUIRK_EXTERNAL_CONFIG) ||
invalid_bdaddr)
hci_dev_set_flag(hdev, HCI_UNCONFIGURED);
/* For an unconfigured controller it is required to * read at least the version information provided by * the Read Local Version Information command. * * If the set_bdaddr driver callback is provided, then * also the original Bluetooth public device address * will be read using the Read BD Address command.
*/ if (hci_dev_test_flag(hdev, HCI_UNCONFIGURED)) return hci_unconf_init_sync(hdev);
return ret;
}
/* This function handles hdev init stage: * * Calls hci_dev_setup_sync to perform setup stage * Calls hci_init_sync to perform HCI command init sequence
*/ staticint hci_dev_init_sync(struct hci_dev *hdev)
{ int ret;
if (hci_dev_test_flag(hdev, HCI_CONFIG)) { /* If public address change is configured, ensure that * the address gets programmed. If the driver does not * support changing the public address, fail the power * on procedure.
*/ if (bacmp(&hdev->public_addr, BDADDR_ANY) &&
hdev->set_bdaddr)
ret = hdev->set_bdaddr(hdev, &hdev->public_addr); else
ret = -EADDRNOTAVAIL;
}
if (!ret) { if (!hci_dev_test_flag(hdev, HCI_UNCONFIGURED) &&
!hci_dev_test_flag(hdev, HCI_USER_CHANNEL)) {
ret = hci_init_sync(hdev); if (!ret && hdev->post_init)
ret = hdev->post_init(hdev);
}
}
/* If the HCI Reset command is clearing all diagnostic settings, * then they need to be reprogrammed after the init procedure * completed.
*/ if (hci_test_quirk(hdev, HCI_QUIRK_NON_PERSISTENT_DIAG) &&
!hci_dev_test_flag(hdev, HCI_USER_CHANNEL) &&
hci_dev_test_flag(hdev, HCI_VENDOR_DIAG) && hdev->set_diag)
ret = hdev->set_diag(hdev, true);
if (!hci_dev_test_flag(hdev, HCI_USER_CHANNEL)) {
msft_do_open(hdev);
aosp_do_open(hdev);
}
clear_bit(HCI_INIT, &hdev->flags);
return ret;
}
int hci_dev_open_sync(struct hci_dev *hdev)
{ int ret;
bt_dev_dbg(hdev, "");
if (hci_dev_test_flag(hdev, HCI_UNREGISTER)) {
ret = -ENODEV; goto done;
}
if (!hci_dev_test_flag(hdev, HCI_SETUP) &&
!hci_dev_test_flag(hdev, HCI_CONFIG)) { /* Check for rfkill but allow the HCI setup stage to * proceed (which in itself doesn't cause any RF activity).
*/ if (hci_dev_test_flag(hdev, HCI_RFKILLED)) {
ret = -ERFKILL; goto done;
}
/* Check for valid public address or a configured static * random address, but let the HCI setup proceed to * be able to determine if there is a public address * or not. * * In case of user channel usage, it is not important * if a public address or static random address is * available.
*/ if (!hci_dev_test_flag(hdev, HCI_USER_CHANNEL) &&
!bacmp(&hdev->bdaddr, BDADDR_ANY) &&
!bacmp(&hdev->static_addr, BDADDR_ANY)) {
ret = -EADDRNOTAVAIL; goto done;
}
}
if (test_bit(HCI_UP, &hdev->flags)) {
ret = -EALREADY; goto done;
}
/* Since hci_rx_work() is possible to awake new cmd_work * it should be flushed first to avoid unexpected call of * hci_cmd_work()
*/
flush_work(&hdev->rx_work);
flush_work(&hdev->cmd_work);
staticint hci_dev_shutdown(struct hci_dev *hdev)
{ int err = 0; /* Similar to how we first do setup and then set the exclusive access * bit for userspace, we must first unset userchannel and then clean up. * Otherwise, the kernel can't properly use the hci channel to clean up * the controller (some shutdown routines require sending additional * commands to the controller for example).
*/ bool was_userchannel =
hci_dev_test_and_clear_flag(hdev, HCI_USER_CHANNEL);
if (!hci_dev_test_flag(hdev, HCI_UNREGISTER) &&
test_bit(HCI_UP, &hdev->flags)) { /* Execute vendor specific shutdown routine */ if (hdev->shutdown)
err = hdev->shutdown(hdev);
}
if (was_userchannel)
hci_dev_set_flag(hdev, HCI_USER_CHANNEL);
return err;
}
int hci_dev_close_sync(struct hci_dev *hdev)
{ bool auto_off; int err = 0;
if (!auto_off && !hci_dev_test_flag(hdev, HCI_USER_CHANNEL) &&
hci_dev_test_flag(hdev, HCI_MGMT))
__mgmt_power_off(hdev);
hci_inquiry_cache_flush(hdev);
hci_pend_le_actions_clear(hdev);
hci_conn_hash_flush(hdev); /* Prevent data races on hdev->smp_data or hdev->smp_bredr_data */
smp_unregister(hdev);
hci_dev_unlock(hdev);
hci_sock_dev_event(hdev, HCI_DEV_DOWN);
if (!hci_dev_test_flag(hdev, HCI_USER_CHANNEL)) {
aosp_do_close(hdev);
msft_do_close(hdev);
}
/* This function perform power on HCI command sequence as follows: * * If controller is already up (HCI_UP) performs hci_powered_update_sync * sequence otherwise run hci_dev_open_sync which will follow with * hci_powered_update_sync after the init sequence is completed.
*/ staticint hci_power_on_sync(struct hci_dev *hdev)
{ int err;
err = hci_dev_open_sync(hdev); if (err < 0) return err;
/* During the HCI setup phase, a few error conditions are * ignored and they need to be checked now. If they are still * valid, it is important to return the device back off.
*/ if (hci_dev_test_flag(hdev, HCI_RFKILLED) ||
hci_dev_test_flag(hdev, HCI_UNCONFIGURED) ||
(!bacmp(&hdev->bdaddr, BDADDR_ANY) &&
!bacmp(&hdev->static_addr, BDADDR_ANY))) {
hci_dev_clear_flag(hdev, HCI_AUTO_OFF);
hci_dev_close_sync(hdev);
} elseif (hci_dev_test_flag(hdev, HCI_AUTO_OFF)) {
queue_delayed_work(hdev->req_workqueue, &hdev->power_off,
HCI_AUTO_OFF_TIMEOUT);
}
if (hci_dev_test_and_clear_flag(hdev, HCI_SETUP)) { /* For unconfigured devices, set the HCI_RAW flag * so that userspace can easily identify them.
*/ if (hci_dev_test_flag(hdev, HCI_UNCONFIGURED))
set_bit(HCI_RAW, &hdev->flags);
/* For fully configured devices, this will send * the Index Added event. For unconfigured devices, * it will send Unconfigued Index Added event. * * Devices with HCI_QUIRK_RAW_DEVICE are ignored * and no event will be send.
*/
mgmt_index_added(hdev);
} elseif (hci_dev_test_and_clear_flag(hdev, HCI_CONFIG)) { /* When the controller is now configured, then it * is important to clear the HCI_RAW flag.
*/ if (!hci_dev_test_flag(hdev, HCI_UNCONFIGURED))
clear_bit(HCI_RAW, &hdev->flags);
/* Powering on the controller with HCI_CONFIG set only * happens with the transition from unconfigured to * configured. This will send the Index Added event.
*/
mgmt_index_added(hdev);
}
if (conn->type == BIS_LINK || conn->type == PA_LINK) { /* This is a BIS connection, hci_conn_del will * do the necessary cleanup.
*/
hci_dev_lock(hdev);
hci_conn_failed(conn, reason);
hci_dev_unlock(hdev);
/* Wait for HCI_EV_DISCONN_COMPLETE, not HCI_EV_CMD_STATUS, when the * reason is anything but HCI_ERROR_REMOTE_POWER_OFF. This reason is * used when suspending or powering off, where we don't want to wait * for the peer's response.
*/ if (reason != HCI_ERROR_REMOTE_POWER_OFF) return __hci_cmd_sync_status_sk(hdev, HCI_OP_DISCONNECT, sizeof(cp), &cp,
HCI_EV_DISCONN_COMPLETE,
HCI_CMD_TIMEOUT, NULL);
if (conn->type == CIS_LINK) { /* BLUETOOTH CORE SPECIFICATION Version 5.3 | Vol 4, Part E * page 1857: * * If this command is issued for a CIS on the Central and the * CIS is successfully terminated before being established, * then an HCI_LE_CIS_Established event shall also be sent for * this CIS with the Status Operation Cancelled by Host (0x44).
*/ if (test_bit(HCI_CONN_CREATE_CIS, &conn->flags)) return hci_disconnect_sync(hdev, conn, reason);
/* CIS with no Create CIS sent have nothing to cancel */ return HCI_ERROR_LOCAL_HOST_TERM;
}
if (conn->type == BIS_LINK || conn->type == PA_LINK) { /* There is no way to cancel a BIS without terminating the BIG * which is done later on connection cleanup.
*/ return 0;
}
if (hdev->hci_ver < BLUETOOTH_VER_1_2) return 0;
/* Wait for HCI_EV_CONN_COMPLETE, not HCI_EV_CMD_STATUS, when the * reason is anything but HCI_ERROR_REMOTE_POWER_OFF. This reason is * used when suspending or powering off, where we don't want to wait * for the peer's response.
*/ if (reason != HCI_ERROR_REMOTE_POWER_OFF) return __hci_cmd_sync_status_sk(hdev, HCI_OP_CREATE_CONN_CANCEL,
6, &conn->dst,
HCI_EV_CONN_COMPLETE,
HCI_CMD_TIMEOUT, NULL);
/* SCO rejection has its own limited set of * allowed error values (0x0D-0x0F).
*/ if (reason < 0x0d || reason > 0x0f)
cp.reason = HCI_ERROR_REJ_LIMITED_RESOURCES;
switch (conn->state) { case BT_CONNECTED: case BT_CONFIG:
err = hci_disconnect_sync(hdev, conn, reason); break; case BT_CONNECT:
err = hci_connect_cancel_sync(hdev, conn, reason); break; case BT_CONNECT2:
err = hci_reject_conn_sync(hdev, conn, reason); break; case BT_OPEN: case BT_BOUND: break; default:
disconnect = true; break;
}
hci_dev_lock(hdev);
/* Check if the connection has been cleaned up concurrently */
c = hci_conn_hash_lookup_handle(hdev, handle); if (!c || c != conn) {
err = 0; goto unlock;
}
/* Cleanup hci_conn object if it cannot be cancelled as it * likely means the controller and host stack are out of sync * or in case of LE it was still scanning so it can be cleanup * safely.
*/ if (disconnect) {
conn->state = BT_CLOSED;
hci_disconn_cfm(conn, reason);
hci_conn_del(conn);
} else {
hci_conn_failed(conn, reason);
}
rcu_read_lock(); while ((conn = list_first_or_null_rcu(head, struct hci_conn, list))) { /* Make sure the connection is not freed while unlocking */
conn = hci_conn_get(conn);
rcu_read_unlock(); /* Disregard possible errors since hci_conn_del shall have been * called even in case of errors had occurred since it would * then cause hci_conn_failed to be called which calls * hci_conn_del internally.
*/
hci_abort_conn_sync(hdev, conn, reason);
hci_conn_put(conn);
rcu_read_lock();
}
rcu_read_unlock();
return 0;
}
/* This function perform power off HCI command sequence as follows: * * Clear Advertising * Stop Discovery * Disconnect all connections * hci_dev_close_sync
*/ staticint hci_power_off_sync(struct hci_dev *hdev)
{ int err;
/* If controller is already down there is nothing to do */ if (!test_bit(HCI_UP, &hdev->flags)) return 0;
hci_dev_set_flag(hdev, HCI_POWERING_DOWN);
if (test_bit(HCI_ISCAN, &hdev->flags) ||
test_bit(HCI_PSCAN, &hdev->flags)) {
err = hci_write_scan_enable_sync(hdev, 0x00); if (err) goto out;
}
err = hci_clear_adv_sync(hdev, NULL, false); if (err) goto out;
err = hci_stop_discovery_sync(hdev); if (err) goto out;
/* Terminated due to Power Off */
err = hci_disconnect_all_sync(hdev, HCI_ERROR_REMOTE_POWER_OFF); if (err) goto out;
int hci_update_discoverable_sync(struct hci_dev *hdev)
{ int err = 0;
if (hci_dev_test_flag(hdev, HCI_BREDR_ENABLED)) {
err = hci_write_iac_sync(hdev); if (err) return err;
err = hci_update_scan_sync(hdev); if (err) return err;
err = hci_update_class_sync(hdev); if (err) return err;
}
/* Advertising instances don't use the global discoverable setting, so * only update AD if advertising was enabled using Set Advertising.
*/ if (hci_dev_test_flag(hdev, HCI_ADVERTISING)) {
err = hci_update_adv_data_sync(hdev, 0x00); if (err) return err;
/* Discoverable mode affects the local advertising * address in limited privacy mode.
*/ if (hci_dev_test_flag(hdev, HCI_LIMITED_PRIVACY)) { if (ext_adv_capable(hdev))
err = hci_start_ext_adv_sync(hdev, 0x00); else
err = hci_enable_advertising_sync(hdev);
}
}
int hci_update_discoverable(struct hci_dev *hdev)
{ /* Only queue if it would have any effect */ if (hdev_is_powered(hdev) &&
hci_dev_test_flag(hdev, HCI_ADVERTISING) &&
hci_dev_test_flag(hdev, HCI_DISCOVERABLE) &&
hci_dev_test_flag(hdev, HCI_LIMITED_PRIVACY)) return hci_cmd_sync_queue(hdev, update_discoverable_sync, NULL,
NULL);
return 0;
}
int hci_update_connectable_sync(struct hci_dev *hdev)
{ int err;
err = hci_update_scan_sync(hdev); if (err) return err;
/* If BR/EDR is not enabled and we disable advertising as a * by-product of disabling connectable, we need to update the * advertising flags.
*/ if (!hci_dev_test_flag(hdev, HCI_BREDR_ENABLED))
err = hci_update_adv_data_sync(hdev, hdev->cur_adv_instance);
/* Update the advertising parameters if necessary */ if (hci_dev_test_flag(hdev, HCI_ADVERTISING) ||
!list_empty(&hdev->adv_instances)) { if (ext_adv_capable(hdev))
err = hci_start_ext_adv_sync(hdev,
hdev->cur_adv_instance); else
err = hci_enable_advertising_sync(hdev);
staticint hci_active_scan_sync(struct hci_dev *hdev, uint16_t interval)
{
u8 own_addr_type; /* Accept list is not used for discovery */
u8 filter_policy = 0x00; /* Default is to enable duplicates filter */
u8 filter_dup = LE_SCAN_FILTER_DUP_ENABLE; int err;
bt_dev_dbg(hdev, "");
/* If controller is scanning, it means the passive scanning is * running. Thus, we should temporarily stop it in order to set the * discovery scanning parameters.
*/
err = hci_scan_disable_sync(hdev); if (err) {
bt_dev_err(hdev, "Unable to disable scanning: %d", err); return err;
}
cancel_interleave_scan(hdev);
/* Pause address resolution for active scan and stop advertising if * privacy is enabled.
*/
err = hci_pause_addr_resolution(hdev); if (err) goto failed;
/* All active scans will be done with either a resolvable private * address (when privacy feature has been enabled) or non-resolvable * private address.
*/
err = hci_update_random_address_sync(hdev, true, scan_use_rpa(hdev),
&own_addr_type); if (err < 0)
own_addr_type = ADDR_LE_DEV_PUBLIC;
if (hci_is_adv_monitoring(hdev) ||
(hci_test_quirk(hdev, HCI_QUIRK_STRICT_DUPLICATE_FILTER) &&
hdev->discovery.result_filtering)) { /* Duplicate filter should be disabled when some advertisement * monitor is activated, otherwise AdvMon can only receive one * advertisement for one peer(*) during active scanning, and * might report loss to these peers. * * If controller does strict duplicate filtering and the * discovery requires result filtering disables controller based * filtering since that can cause reports that would match the * host filter to not be reported.
*/
filter_dup = LE_SCAN_FILTER_DUP_DISABLE;
}
switch (hdev->discovery.type) { case DISCOV_TYPE_BREDR: return hci_inquiry_sync(hdev, DISCOV_BREDR_INQUIRY_LEN, 0); case DISCOV_TYPE_INTERLEAVED: /* When running simultaneous discovery, the LE scanning time * should occupy the whole discovery time sine BR/EDR inquiry * and LE scanning are scheduled by the controller. * * For interleaving discovery in comparison, BR/EDR inquiry * and LE scanning are done sequentially with separate * timeouts.
*/ if (hci_test_quirk(hdev, HCI_QUIRK_SIMULTANEOUS_DISCOVERY)) {
timeout = msecs_to_jiffies(DISCOV_LE_TIMEOUT); /* During simultaneous discovery, we double LE scan * interval. We must leave some time for the controller * to do BR/EDR inquiry.
*/
err = hci_start_interleaved_discovery_sync(hdev); break;
}
/* This function disables discovery and mark it as paused */ staticint hci_pause_discovery_sync(struct hci_dev *hdev)
{ int old_state = hdev->discovery.state; int err;
/* If discovery already stopped/stopping/paused there nothing to do */ if (old_state == DISCOVERY_STOPPED || old_state == DISCOVERY_STOPPING ||
hdev->discovery_paused) return 0;
hci_discovery_set_state(hdev, DISCOVERY_STOPPING);
err = hci_stop_discovery_sync(hdev); if (err) return err;
if (!hci_dev_test_flag(hdev, HCI_BREDR_ENABLED)) return 0;
/* Some fake CSR controllers lock up after setting this type of * filter, so avoid sending the request altogether.
*/ if (hci_test_quirk(hdev, HCI_QUIRK_BROKEN_FILTER_CLEAR_ALL)) return 0;
/* Always clear event filter when starting */
hci_clear_event_filter_sync(hdev);
list_for_each_entry(b, &hdev->accept_list, list) { if (!(b->flags & HCI_CONN_FLAG_REMOTE_WAKEUP)) continue;
bt_dev_dbg(hdev, "Adding event filters for %pMR", &b->bdaddr);
err = hci_set_event_filter_sync(hdev, HCI_FLT_CONN_SETUP,
HCI_CONN_SETUP_ALLOW_BDADDR,
&b->bdaddr,
HCI_CONN_SETUP_AUTO_ON); if (err)
bt_dev_err(hdev, "Failed to set event filter for %pMR",
&b->bdaddr); else
scan = SCAN_PAGE;
}
/* This function disables scan (BR and LE) and mark it as paused */ staticint hci_pause_scan_sync(struct hci_dev *hdev)
{ if (hdev->scanning_paused) return 0;
/* Disable page scan if enabled */ if (test_bit(HCI_PSCAN, &hdev->flags))
hci_write_scan_enable_sync(hdev, SCAN_DISABLED);
hci_scan_disable_sync(hdev);
hdev->scanning_paused = true;
return 0;
}
/* This function performs the HCI suspend procedures in the follow order: * * Pause discovery (active scanning/inquiry) * Pause Directed Advertising/Advertising * Pause Scanning (passive scanning in case discovery was not active) * Disconnect all connections * Set suspend_status to BT_SUSPEND_DISCONNECT if hdev cannot wakeup * otherwise: * Update event mask (only set events that are allowed to wake up the host) * Update event filter (with devices marked with HCI_CONN_FLAG_REMOTE_WAKEUP) * Update passive scanning (lower duty cycle) * Set suspend_status to BT_SUSPEND_CONFIGURE_WAKE
*/ int hci_suspend_sync(struct hci_dev *hdev)
{ int err;
/* If marked as suspended there nothing to do */ if (hdev->suspended) return 0;
/* Mark device as suspended */
hdev->suspended = true;
/* Pause discovery if not already stopped */
hci_pause_discovery_sync(hdev);
/* Pause other advertisements */
hci_pause_advertising_sync(hdev);
/* Prevent disconnects from causing scanning to be re-enabled */
hci_pause_scan_sync(hdev);
if (hci_conn_count(hdev)) { /* Soft disconnect everything (power off) */
err = hci_disconnect_all_sync(hdev, HCI_ERROR_REMOTE_POWER_OFF); if (err) { /* Set state to BT_RUNNING so resume doesn't notify */
hdev->suspend_state = BT_RUNNING;
hci_resume_sync(hdev); return err;
}
/* Update event mask so only the allowed event can wakeup the * host.
*/
hci_set_event_mask_sync(hdev);
}
/* Only configure accept list if disconnect succeeded and wake * isn't being prevented.
*/ if (!hdev->wakeup || !hdev->wakeup(hdev)) {
hdev->suspend_state = BT_SUSPEND_DISCONNECT; return 0;
}
/* Unpause to take care of updating scanning params */
hdev->scanning_paused = false;
/* Enable event filter for paired devices */
hci_update_event_filter_sync(hdev);
/* Update LE passive scan if enabled */
hci_update_passive_scan_sync(hdev);
/* This function resume scan and reset paused flag */ staticint hci_resume_scan_sync(struct hci_dev *hdev)
{ if (!hdev->scanning_paused) return 0;
hdev->scanning_paused = false;
hci_update_scan_sync(hdev);
/* Reset passive scanning to normal */
hci_update_passive_scan_sync(hdev);
return 0;
}
/* This function performs the HCI suspend procedures in the follow order: * * Restore event mask * Clear event filter * Update passive scanning (normal duty cycle) * Resume Directed Advertising/Advertising * Resume discovery (active scanning/inquiry)
*/ int hci_resume_sync(struct hci_dev *hdev)
{ /* If not marked as suspended there nothing to do */ if (!hdev->suspended) return 0;
err = hci_update_random_address_sync(hdev, false, conn_use_rpa(conn),
&own_addr_type); if (err) return err;
/* Set require_privacy to false so that the remote device has a * chance of identifying us.
*/
err = hci_get_random_address(hdev, false, conn_use_rpa(conn), NULL,
&own_addr_type, &random_addr); if (err) return err;
/* As per Core Spec 5.2 Vol 2, PART E, Sec 7.8.53, for * advertising_event_property LE_LEGACY_ADV_DIRECT_IND * does not supports advertising data when the advertising set already * contains some, the controller shall return erroc code 'Invalid * HCI Command Parameters(0x12). * So it is required to remove adv set for handle 0x00. since we use * instance 0 for directed adv.
*/
err = hci_remove_ext_adv_instance_sync(hdev, cp.handle, NULL); if (err) return err;
err = hci_set_ext_adv_params_sync(hdev, NULL, &cp, &rp); if (err) return err;
/* Update adv data as tx power is known now */
err = hci_set_ext_adv_data_sync(hdev, cp.handle); if (err) return err;
/* Check if random address need to be updated */ if (own_addr_type == ADDR_LE_DEV_RANDOM &&
bacmp(&random_addr, BDADDR_ANY) &&
bacmp(&random_addr, &hdev->random_addr)) {
err = hci_set_adv_set_random_addr_sync(hdev, 0x00,
&random_addr); if (err) return err;
}
if (ext_adv_capable(hdev)) return hci_le_ext_directed_advertising_sync(hdev, conn);
/* Clear the HCI_LE_ADV bit temporarily so that the * hci_update_random_address knows that it's safe to go ahead * and write a new random address. The flag will be set back on * as soon as the SET_ADV_ENABLE HCI command completes.
*/
hci_dev_clear_flag(hdev, HCI_LE_ADV);
/* Set require_privacy to false so that the remote device has a * chance of identifying us.
*/
status = hci_update_random_address_sync(hdev, false, conn_use_rpa(conn),
&own_addr_type); if (status) return status;
memset(&cp, 0, sizeof(cp));
/* Some controllers might reject command if intervals are not * within range for undirected advertising. * BCM20702A0 is known to be affected by this.
*/
cp.min_interval = cpu_to_le16(0x0020);
cp.max_interval = cpu_to_le16(0x0020);
/* If requested to connect as peripheral use directed advertising */ if (conn->role == HCI_ROLE_SLAVE) { /* If we're active scanning and simultaneous roles is not * enabled simply reject the attempt.
*/ if (hci_dev_test_flag(hdev, HCI_LE_SCAN) &&
hdev->le_scan_type == LE_SCAN_ACTIVE &&
!hci_dev_test_flag(hdev, HCI_LE_SIMULTANEOUS_ROLES)) {
hci_conn_del(conn); return -EBUSY;
}
/* Pause advertising while doing directed advertising. */
hci_pause_advertising_sync(hdev);
/* Disable advertising if simultaneous roles is not in use. */ if (!hci_dev_test_flag(hdev, HCI_LE_SIMULTANEOUS_ROLES))
hci_pause_advertising_sync(hdev);
/* If controller is scanning, we stop it since some controllers are * not able to scan and connect at the same time. Also set the * HCI_LE_SCAN_INTERRUPTED flag so that the command complete * handler for scan disabling knows to set the correct discovery * state.
*/ if (hci_dev_test_flag(hdev, HCI_LE_SCAN)) {
hci_scan_disable_sync(hdev);
hci_dev_set_flag(hdev, HCI_LE_SCAN_INTERRUPTED);
}
/* Update random address, but set require_privacy to false so * that we never connect with an non-resolvable address.
*/
err = hci_update_random_address_sync(hdev, false, conn_use_rpa(conn),
&own_addr_type); if (err) goto done; /* Send command LE Extended Create Connection if supported */ if (use_ext_conn(hdev)) {
err = hci_le_ext_create_conn_sync(hdev, conn, own_addr_type); goto done;
}
/* BLUETOOTH CORE SPECIFICATION Version 5.3 | Vol 4, Part E page 2261: * * If this event is unmasked and the HCI_LE_Connection_Complete event * is unmasked, only the HCI_LE_Enhanced_Connection_Complete event is * sent when a new connection has been created.
*/
err = __hci_cmd_sync_status_sk(hdev, HCI_OP_LE_CREATE_CONN, sizeof(cp), &cp,
use_enhanced_conn_complete(hdev) ?
HCI_EV_LE_ENHANCED_CONN_COMPLETE :
HCI_EV_LE_CONN_COMPLETE,
conn->conn_timeout, NULL);
done: if (err == -ETIMEDOUT)
hci_le_connect_cancel_sync(hdev, conn, 0x00);
/* Re-enable advertising after the connection attempt is finished. */
hci_resume_advertising_sync(hdev); return err;
}
/* The spec allows only one pending LE Create CIS command at a time. If * the command is pending now, don't do anything. We check for pending * connections after each CIS Established event. * * BLUETOOTH CORE SPECIFICATION Version 5.3 | Vol 4, Part E * page 2566: * * If the Host issues this command before all the * HCI_LE_CIS_Established events from the previous use of the * command have been generated, the Controller shall return the * error code Command Disallowed (0x0C). * * BLUETOOTH CORE SPECIFICATION Version 5.3 | Vol 4, Part E * page 2567: * * When the Controller receives the HCI_LE_Create_CIS command, the * Controller sends the HCI_Command_Status event to the Host. An * HCI_LE_CIS_Established event will be generated for each CIS when it * is established or if it is disconnected or considered lost before * being established; until all the events are generated, the command * remains pending.
*/
hci_dev_lock(hdev);
rcu_read_lock();
/* Wait until previous Create CIS has completed */
list_for_each_entry_rcu(conn, &hdev->conn_hash.list, list) { if (test_bit(HCI_CONN_CREATE_CIS, &conn->flags)) goto done;
}
/* Find CIG with all CIS ready */
list_for_each_entry_rcu(conn, &hdev->conn_hash.list, list) { struct hci_conn *link;
int hci_get_random_address(struct hci_dev *hdev, bool require_privacy, bool use_rpa, struct adv_info *adv_instance,
u8 *own_addr_type, bdaddr_t *rand_addr)
{ int err;
bacpy(rand_addr, BDADDR_ANY);
/* If privacy is enabled use a resolvable private address. If * current RPA has expired then generate a new one.
*/ if (use_rpa) { /* If Controller supports LL Privacy use own address type is * 0x03
*/ if (ll_privacy_capable(hdev))
*own_addr_type = ADDR_LE_DEV_RANDOM_RESOLVED; else
*own_addr_type = ADDR_LE_DEV_RANDOM;
if (adv_instance) { if (adv_rpa_valid(adv_instance)) return 0;
} else { if (rpa_valid(hdev)) return 0;
}
err = smp_generate_rpa(hdev, hdev->irk, &hdev->rpa); if (err < 0) {
bt_dev_err(hdev, "failed to generate new RPA"); return err;
}
bacpy(rand_addr, &hdev->rpa);
return 0;
}
/* In case of required privacy without resolvable private address, * use an non-resolvable private address. This is useful for * non-connectable advertising.
*/ if (require_privacy) {
bdaddr_t nrpa;
while (true) { /* The non-resolvable private address is generated * from random six bytes with the two most significant * bits cleared.
*/
get_random_bytes(&nrpa, 6);
nrpa.b[5] &= 0x3f;
/* The non-resolvable private address shall not be * equal to the public address.
*/ if (bacmp(&hdev->bdaddr, &nrpa)) break;
}
if (!hci_conn_valid(hdev, conn)) return -ECANCELED;
/* Many controllers disallow HCI Create Connection while it is doing * HCI Inquiry. So we cancel the Inquiry first before issuing HCI Create * Connection. This may cause the MGMT discovering state to become false * without user space's request but it is okay since the MGMT Discovery * APIs do not promise that discovery should be done forever. Instead, * the user space monitors the status of MGMT discovering and it may * request for discovery again when this flag becomes false.
*/ if (test_bit(HCI_INQUIRY, &hdev->flags)) {
err = __hci_cmd_sync_status(hdev, HCI_OP_INQUIRY_CANCEL, 0,
NULL, HCI_CMD_TIMEOUT); if (err)
bt_dev_warn(hdev, "Failed to cancel inquiry %d", err);
}
if (!err) {
hci_connect_le_scan_cleanup(conn, 0x00); goto done;
}
/* Check if connection is still pending */ if (conn != hci_lookup_le_connect(hdev)) goto done;
/* Flush to make sure we send create conn cancel command if needed */
flush_delayed_work(&conn->le_conn_timeout);
hci_conn_failed(conn, bt_status(err));
if (!hci_conn_valid(hdev, conn)) return -ECANCELED;
if (conn->sync_handle != HCI_SYNC_HANDLE_INVALID) return -EINVAL;
if (hci_dev_test_and_set_flag(hdev, HCI_PA_SYNC)) return -EBUSY;
/* Stop scanning if SID has not been set and active scanning is enabled * so we use passive scanning which will be scanning using the allow * list programmed to contain only the connection address.
*/ if (conn->sid == HCI_SID_INVALID &&
hci_dev_test_flag(hdev, HCI_LE_SCAN)) {
hci_scan_disable_sync(hdev);
hci_dev_set_flag(hdev, HCI_LE_SCAN_INTERRUPTED);
hci_discovery_set_state(hdev, DISCOVERY_STOPPED);
}
/* Mark HCI_CONN_CREATE_PA_SYNC so hci_update_passive_scan_sync can * program the address in the allow list so PA advertisements can be * received.
*/
set_bit(HCI_CONN_CREATE_PA_SYNC, &conn->flags);
hci_update_passive_scan_sync(hdev);
/* SID has not been set listen for HCI_EV_LE_EXT_ADV_REPORT to update * it.
*/ if (conn->sid == HCI_SID_INVALID) {
err = __hci_cmd_sync_status_sk(hdev, HCI_OP_NOP, 0, NULL,
HCI_EV_LE_EXT_ADV_REPORT,
conn->conn_timeout, NULL); if (err == -ETIMEDOUT) goto done;
}
/* The spec allows only one pending LE Periodic Advertising Create * Sync command at a time so we forcefully wait for PA Sync Established * event since cmd_work can only schedule one command at a time. * * BLUETOOTH CORE SPECIFICATION Version 5.3 | Vol 4, Part E * page 2493: * * If the Host issues this command when another HCI_LE_Periodic_ * Advertising_Create_Sync command is pending, the Controller shall * return the error code Command Disallowed (0x0C).
*/
err = __hci_cmd_sync_status_sk(hdev, HCI_OP_LE_PA_CREATE_SYNC, sizeof(cp), &cp,
HCI_EV_LE_PA_SYNC_ESTABLISHED,
conn->conn_timeout, NULL); if (err == -ETIMEDOUT)
__hci_cmd_sync_status(hdev, HCI_OP_LE_PA_CREATE_SYNC_CANCEL,
0, NULL, HCI_CMD_TIMEOUT);
done:
hci_dev_clear_flag(hdev, HCI_PA_SYNC);
/* Update passive scan since HCI_PA_SYNC flag has been cleared */
hci_update_passive_scan_sync(hdev);
/* The spec allows only one pending LE BIG Create Sync command at * a time, so we forcefully wait for BIG Sync Established event since * cmd_work can only schedule one command at a time. * * BLUETOOTH CORE SPECIFICATION Version 5.3 | Vol 4, Part E * page 2586: * * If the Host sends this command when the Controller is in the * process of synchronizing to any BIG, i.e. the HCI_LE_BIG_Sync_ * Established event has not been generated, the Controller shall * return the error code Command Disallowed (0x0C).
*/
err = __hci_cmd_sync_status_sk(hdev, HCI_OP_LE_BIG_CREATE_SYNC,
struct_size(cp, bis, cp->num_bis), cp,
HCI_EVT_LE_BIG_SYNC_ESTABLISHED,
conn->conn_timeout, NULL); if (err == -ETIMEDOUT)
hci_le_big_terminate_sync(hdev, cp->handle);
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.