/* Grab a reference if command needs to be associated with a sock (e.g. *likelymgmtsocketthatinitiatedthecommand).
*/ if (sk) {
hci_skb_sk(skb) = sk;
sock_hold(sk);
}
/* If an error occurred during request building, remove all HCI *commandsqueuedontheHCIrequestqueue.
*/ 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 *wewererunningbothLEandBR/EDRinquirysimultaneously, *andBR/EDRinquiryisalreadyfinished,stopdiscovery, *otherwiseBR/EDRinquirywillstopdiscoverywhenfinished. *Ifwewillresolveremotedevicename,donotchange *discoverystate.
*/
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:Theinstancewillberemovedevenwhenitsremaining *lifetimeisnotzero. *-force==false:theinstancewillbedeactivatedbutkeptstoredunless *theremaininglifetimeiszero. * *Forinstance==0x00: *-force==true:Allinstanceswillberemovedregardlessoftheirtimeout *setting. *-force==false:Onlyinstancesthathaveatimeoutwillberemoved.
*/ 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 *thecurrentone.Thiscanbethesameinstanceagain *ifthereisonlyoneinstance.
*/ 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);
}
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: * *-hdevmust_not_beunregistered
*/ 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: * *-hdevmustberunning
*/ 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 *andiseitheroninitphaseorisalreadyup.
*/ if (!test_bit(HCI_RUNNING, &hdev->flags)) return -ENETDOWN;
/* Run HCI command: * *-hdevmustberunning *-ifoncmd_sync_workthenrunimmediatelyotherwisequeue
*/ 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 *andiseitheroninitphaseorisalreadyup.
*/ 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);
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 *bit20.
*/ if (!connectable && !(hdev->le_states[2] & 0x10)) returnfalse;
/* Peripheral connection state and connectable mode bit 38 *andscannablebit21.
*/ 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 *scannable19.
*/ 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 *bothdiscoverableandbondable.
*/ if ((flags & MGMT_ADV_FLAG_DISCOV) &&
hci_dev_test_flag(hdev, HCI_BONDABLE)) returnfalse;
/* We're neither bondable nor discoverable in the limited *privacymode,thereforeuseRPA.
*/ 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 *connectionwecan'tgoaheadandchangetherandomaddressatthis *time.Thisisbecausetheeventualinitiatoraddressusedforthe *subsequentlycreatedconnectionwillbeundefined(some *controllersusethenewaddressandotherstheonewehad *whentheoperationstarted). * *Inthiskindofscenarioskiptheupdateandlettherandom *addressbeupdatedatthenextcycle.
*/ 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); return0;
}
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 *currentRPAhasexpiredorthereissomethingelsethan *thecurrentRPAinuse,thengenerateanewone.
*/ 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)) return0;
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;
return0;
}
/* In case of required privacy without resolvable private address, *useannon-resolvableprivateaddress.Thisisusefulforactive *scanningandnon-connectableadvertising.
*/ if (require_privacy) {
bdaddr_t nrpa;
while (true) { /* The non-resolvable private address is generated *fromrandomsixbyteswiththetwomostsignificant *bitscleared.
*/
get_random_bytes(&nrpa, 6);
nrpa.b[5] &= 0x3f;
/* The non-resolvable private address shall not be *equaltothepublicaddress.
*/ 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 *addressusethestaticaddressasrandomaddress(butskip *theHCIcommandifthecurrentrandomaddressisalreadythe *staticone. * *IncaseBR/EDRhasbeendisabledonadual-modecontroller *andastaticaddresshasbeenconfigured,thenusethat *addressinsteadofthepublicBR/EDRaddress.
*/ 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); return0;
}
/* Neither privacy nor static address is being used so use a *publicaddress.
*/
*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) return0;
}
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 > 0) {
adv = hci_find_adv_instance(hdev, instance); if (!adv) return -EINVAL;
} else {
adv = NULL;
}
/* Updating parameters of an active instance will return a *CommandDisallowederror,sowemustfirstdisablethe *instanceifitisactive.
*/ 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_INDandADV_NONCONN_INDbasedontheglobalconnectablesetting.
*/
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 *advertisingisusedanditisnotperiodic. *Inthatcaseitisfinetouseanon-resolvableprivateaddress.
*/
require_privacy = !connectable && !(adv && adv->periodic);
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)) return0;
} else { if (!bacmp(&random_addr, &hdev->random_addr)) return0;
}
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) return0;
} 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 *schedulingit.
*/ 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) return0;
/* If periodic advertising already enabled there is nothing to do. */
adv = hci_find_adv_instance(hdev, instance); if (adv && adv->periodic_enabled) return0;
/* Checks if periodic advertising data contains a Basic Announcement and if it *doesgeneratesaBroadcastIDandaddBroadcastAnnouncement.
*/ 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 *advertisingsoitcannotusedforthelikesofBroadcastAnnouncement *asitcanbeoverwrittenatanypoint.
*/ if (!adv) return0;
/* Check if PA data doesn't contains a Basic Audio Announcement then *thereisnothingtodo.
*/ if (!eir_get_service_data(adv->per_adv_data, adv->per_adv_data_len, 0x1851, NULL)) return0;
/* Check if advertising data already has a Broadcast Announcement since *theprocessmaywanttocontroltheBroadcastIDdirectlyandinthat *casethekernelshallnointerfere.
*/ if (eir_get_service_data(adv->adv_data, adv->adv_data_len, 0x1852,
NULL)) return0;
/* 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_INDandADV_NONCONN_INDbasedontheglobalconnectablesetting.
*/
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_addressknowsthatit'ssafetogoahead *andwriteanewrandomaddress.Theflagwillbesetbackon *assoonastheSET_ADV_ENABLEHCIcommandcompletes.
*/
hci_dev_clear_flag(hdev, HCI_LE_ADV);
/* Set require_privacy to true only when non-connectable *advertisingisused.Inthatcaseitisfinetousea *non-resolvableprivateaddress.
*/
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 *onlyoneinstance,durationshouldbeignored.Westillsetatimeout *incasefurtherinstancesarebeingaddedlateron. * *Iftheremaininglifetimeoftheinstanceismorethantheduration *thenthetimeoutcorrespondstotheduration,otherwiseitwillbe *reducedtotheremaininginstancelifetime.
*/ 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 *advertisedwithouttimelimit.
*/ 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 *executeanyHCIcommands.Thishappenswhenasingleinstanceis *beingadvertised.
*/ if (!force && hdev->cur_adv_instance == instance &&
hci_dev_test_flag(hdev, HCI_LE_ADV)) return0;
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)) return0;
/* 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:Theinstancewillberemovedevenwhenitsremaining *lifetimeisnotzero. *-force==false:theinstancewillbedeactivatedbutkeptstoredunless *theremaininglifetimeiszero. * *Forinstance==0x00: *-force==true:Allinstanceswillberemovedregardlessoftheirtimeout *setting. *-force==false:Onlyinstancesthathaveatimeoutwillberemoved.
*/ 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 *thecurrentone.Thiscanbethesameinstanceagain *ifthereisonlyoneinstance.
*/ 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,returnfalse
*/ staticbool hci_update_interleaved_scan_sync(struct hci_dev *hdev)
{ /* Do interleaved scan only if all of the following are true: *-ThereisatleastoneADVmonitor *-AtleastonependingLEconnectionoronedevicetobescannedfor *-Monitoroffloadingisnotsupported *Ifso,weshouldalternatebetweenallowlistscanandonewithout *anyfilterstosavepower.
*/ 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 *thatthedevicewasneveradded.
*/
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) return0;
/* 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) return0;
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)) return0;
/* If device privacy mode has already been set there is nothing to do */ if (params->privacy_mode == HCI_DEVICE_PRIVACY) return0;
/* Check if HCI_CONN_FLAG_DEVICE_PRIVACY has been set as it also *indicatesthatLLPrivacyhasbeenenabledand *HCI_OP_LE_SET_PRIVACY_MODEissupported.
*/ if (!(params->flags & HCI_CONN_FLAG_DEVICE_PRIVACY)) return0;
irk = hci_find_irk_by_addr(hdev, ¶ms->addr, params->addr_type); if (!irk) return0;
/* Adds connection to allow list if needed, if the device uses RPA (has IRK) *thisattemptstoprogramthedeviceintheresolvinglistaswelland *properlysettheprivacymode.
*/ 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); return0;
}
/* 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 *havingtorollbackincaseitfailssincetheresolvinglistis *dynamicitcanprobablybesmallerthantheacceptlist.
*/
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)) return0;
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);
return0;
}
/* 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)) return0;
/* If already been paused there is nothing to do. */ if (hdev->advertising_paused) return0;
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 *thelimiteddiscoverableflagiscleared.Eveninthecase *ofatimeouttriggeredfromgeneraldiscoverable,itis *safetounconditionallycleartheflag.
*/
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. *Thiswillsucceedevenifnoadvertisementsareconfigured.
*/
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) return0;
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 *thenweneedtore-enableit.
*/ 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 *thesoftwarerotationloop
*/
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)) return0;
if (!hci_dev_test_flag(hdev, HCI_LL_RPA_RESOLUTION)) return0;
/* Cannot disable addr resolution if scanning is enabled or *wheninitiatinganLEconnection.
*/ 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)) return0;
/* Read LE Maximum Data Length */
static int 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 Suggested Default Data Length */
static int hci_le_read_def_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 */
static int hci_le_read_num_support_adv_sets_sync(struct hci_dev *hdev)
{
if (!ext_adv_capable(hdev))
return 0;
static int hci_init3_sync(struct hci_dev *hdev)
{
int err;
bt_dev_dbg(hdev, "");
err = hci_init_stage_sync(hdev, hci_init3);
if (err)
return err;
if (lmp_le_capable(hdev))
return hci_init_stage_sync(hdev, le_init3);
return 0;
}
static int hci_delete_stored_link_key_sync(struct hci_dev *hdev)
{
struct hci_cp_delete_stored_link_key cp;
/* Some Broadcom based Bluetooth controllers do not support the *DeleteStoredLinkKeycommand.Theyareclearlyindicatingits *absenceinthebitmaskofsupportedcommands. * *Checkthesupportedcommandsandonlyifthecommandismarked *assupportedsendit.Ifnotsupportedassumethatthecontroller *doesnothaveactualsupportforstoredlinkkeyswhichmakesthis *commandredundantanyway. * *Somecontrollersindicatethattheysupporthandlingdeleting *storedlinkkeys,buttheydon't.Thequirkletsadriver *justdisablethiscommand.
*/
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 *MaskPage2command,butthenactuallydonotsupportit.Since *thedefaultvalueisallbitssettozero,thecommandisonly *requirediftheeventmaskhastobechanged.Incasenochange *totheeventmaskisneeded,skipthiscommand.
*/
if (!changed)
return 0;
/* Read local codec list if the HCI command is supported */
static int hci_read_local_codecs_sync(struct hci_dev *hdev)
{
if (hdev->commands[45] & 0x04)
hci_read_supported_codecs_v2(hdev);
else if (hdev->commands[29] & 0x20)
hci_read_supported_codecs(hdev);
return 0;
}
/* Read local pairing options if the HCI command is supported */
static int 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 */
static int hci_get_mws_transport_config_sync(struct hci_dev *hdev)
{
if (!mws_transport_config_capable(hdev))
return 0;
/* Check for Synchronization Train support */
static int hci_read_sync_train_params_sync(struct hci_dev *hdev)
{
if (!lmp_sync_train_capable(hdev))
return 0;
/* Set erroneous data reporting if supported to the wideband speech *settingvalue
*/
static int 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 */
static int 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 *PHYsaccordingtotheLEFeaturesbits.
*/
static int 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;
}
static int 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;
}
static int 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 *configuredstate.Whenthecontrollerismarkedasunconfigured, *thisinitializationprocedureisnotrun. * *Itmeansthatitispossiblethatacontrollerrunsthroughits *setupphaseandthendiscoversmissingsettings.Ifthatisthe *case,thenthisfunctionwillnotbecalled.Itthenwillonly *becalledduringtheconfigphase. * *Soonlywheninsetupphaseorconfigphase,createthedebugfs *entriesandregistertheSMPchannels.
*/
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);
static const struct {
unsigned long quirk;
const char *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: * *Callshdev->setup *SetupaddressifHCI_QUIRK_USE_BDADDR_PROPERTYisset.
*/
static int 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_ADDRinvalidbeforecreatingtheHCIdeviceorin *itssetupcallback.
*/
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 *creatingtheHCIdeviceorinitssetupcallback. * *FortheinvalidBD_ADDRquirkitispossiblethat *itbecomesavalidaddressifthebootloaderdoes *provideit(seeabove). * *Incaseanyofthemisset,thecontrollerhasto *startupasunconfigured.
*/
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 *readatleasttheversioninformationprovidedby *theReadLocalVersionInformationcommand. * *Iftheset_bdaddrdrivercallbackisprovided,then *alsotheoriginalBluetoothpublicdeviceaddress *willbereadusingtheReadBDAddresscommand.
*/
if (hci_dev_test_flag(hdev, HCI_UNCONFIGURED))
return hci_unconf_init_sync(hdev);
return ret;
}
/* This function handles hdev init stage: * *Callshci_dev_setup_synctoperformsetupstage *Callshci_init_synctoperformHCIcommandinitsequence
*/
static int 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 *theaddressgetsprogrammed.Ifthedriverdoesnot *supportchangingthepublicaddress,failthepower *onprocedure.
*/
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, *thentheyneedtobereprogrammedaftertheinitprocedure *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(whichinitselfdoesn'tcauseanyRFactivity).
*/
if (hci_dev_test_flag(hdev, HCI_RFKILLED)) {
ret = -ERFKILL;
goto done;
}
/* Check for valid public address or a configured static *randomaddress,butlettheHCIsetupproceedto *beabletodetermineifthereisapublicaddress *ornot. * *Incaseofuserchannelusage,itisnotimportant *ifapublicaddressorstaticrandomaddressis *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 *itshouldbeflushedfirsttoavoidunexpectedcallof *hci_cmd_work()
*/
flush_work(&hdev->rx_work);
flush_work(&hdev->cmd_work);
static int hci_dev_shutdown(struct hci_dev *hdev)
{
int err = 0; /* Similar to how we first do setup and then set the exclusive access *bitforuserspace,wemustfirstunsetuserchannelandthencleanup. *Otherwise,thekernelcan'tproperlyusethehcichanneltocleanup *thecontroller(someshutdownroutinesrequiresendingadditional *commandstothecontrollerforexample).
*/
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: * *Ifcontrollerisalreadyup(HCI_UP)performshci_powered_update_sync *sequenceotherwiserunhci_dev_open_syncwhichwillfollowwith *hci_powered_update_syncaftertheinitsequenceiscompleted.
*/
static int 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 *ignoredandtheyneedtobecheckednow.Iftheyarestill *valid,itisimportanttoreturnthedevicebackoff.
*/
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);
} else if (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 *sothatuserspacecaneasilyidentifythem.
*/
if (hci_dev_test_flag(hdev, HCI_UNCONFIGURED))
set_bit(HCI_RAW, &hdev->flags);
/* For fully configured devices, this will send *theIndexAddedevent.Forunconfigureddevices, *itwillsendUnconfiguedIndexAddedevent. * *DeviceswithHCI_QUIRK_RAW_DEVICEareignored *andnoeventwillbesend.
*/
mgmt_index_added(hdev);
} else if (hci_dev_test_and_clear_flag(hdev, HCI_CONFIG)) { /* When the controller is now configured, then it *isimportanttocleartheHCI_RAWflag.
*/
if (!hci_dev_test_flag(hdev, HCI_UNCONFIGURED))
clear_bit(HCI_RAW, &hdev->flags);
/* Powering on the controller with HCI_CONFIG set only *happenswiththetransitionfromunconfiguredto *configured.ThiswillsendtheIndexAddedevent.
*/
mgmt_index_added(hdev);
}
if (conn->type == BIS_LINK || conn->type == PA_LINK) { /* This is a BIS connection, hci_conn_del will *dothenecessarycleanup.
*/
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 *reasonisanythingbutHCI_ERROR_REMOTE_POWER_OFF.Thisreasonis *usedwhensuspendingorpoweringoff,wherewedon'twanttowait *forthepeer'sresponse.
*/
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);
static int hci_le_connect_cancel_sync(struct hci_dev *hdev,
struct hci_conn *conn, u8 reason)
{ /* Return reason if scanning since the connection shall probably be *cleanupdirectly.
*/
if (test_bit(HCI_CONN_SCANNING, &conn->flags))
return reason;
if (conn->role == HCI_ROLE_SLAVE ||
test_and_set_bit(HCI_CONN_CANCEL, &conn->flags))
return 0;
static int hci_connect_cancel_sync(struct hci_dev *hdev, struct hci_conn *conn,
u8 reason)
{
if (conn->type == LE_LINK)
return hci_le_connect_cancel_sync(hdev, conn, reason);
if (conn->type == CIS_LINK) { /* BLUETOOTH CORE SPECIFICATION Version 5.3 | Vol 4, Part E *page1857: * *IfthiscommandisissuedforaCISontheCentralandthe *CISissuccessfullyterminatedbeforebeingestablished, *thenanHCI_LE_CIS_Establishedeventshallalsobesentfor *thisCISwiththeStatusOperationCancelledbyHost(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 *whichisdonelateronconnectioncleanup.
*/
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 *reasonisanythingbutHCI_ERROR_REMOTE_POWER_OFF.Thisreasonis *usedwhensuspendingorpoweringoff,wherewedon'twanttowait *forthepeer'sresponse.
*/
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 *allowederrorvalues(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 *likelymeansthecontrollerandhoststackareoutofsync *orincaseofLEitwasstillscanningsoitcanbecleanup *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 *calledevenincaseoferrorshadoccurredsinceitwould *thencausehci_conn_failedtobecalledwhichcalls *hci_conn_delinternally.
*/
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: * *ClearAdvertising *StopDiscovery *Disconnectallconnections *hci_dev_close_sync
*/
static int 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 *onlyupdateADifadvertisingwasenabledusingSetAdvertising.
*/ 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 *addressinlimitedprivacymode.
*/ 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);
return0;
}
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-productofdisablingconnectable,weneedtoupdatethe *advertisingflags.
*/ 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,weshouldtemporarilystopitinordertosetthe *discoveryscanningparameters.
*/
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 *privacyisenabled.
*/
err = hci_pause_addr_resolution(hdev); if (err) goto failed;
/* All active scans will be done with either a resolvable private *address(whenprivacyfeaturehasbeenenabled)ornon-resolvable *privateaddress.
*/
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 *monitorisactivated,otherwiseAdvMoncanonlyreceiveone *advertisementforonepeer(*)duringactivescanning,and *mightreportlosstothesepeers. * *Ifcontrollerdoesstrictduplicatefilteringandthe *discoveryrequiresresultfilteringdisablescontrollerbased *filteringsincethatcancausereportsthatwouldmatchthe *hostfiltertonotbereported.
*/
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 *shouldoccupythewholediscoverytimesineBR/EDRinquiry *andLEscanningarescheduledbythecontroller. * *Forinterleavingdiscoveryincomparison,BR/EDRinquiry *andLEscanningaredonesequentiallywithseparate *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.Wemustleavesometimeforthecontroller *todoBR/EDRinquiry.
*/
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) return0;
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)) return0;
/* Some fake CSR controllers lock up after setting this type of *filter,soavoidsendingtherequestaltogether.
*/ if (hci_test_quirk(hdev, HCI_QUIRK_BROKEN_FILTER_CLEAR_ALL)) return0;
/* 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)
{
)
java.lang.StringIndexOutOfBoundsException: Range [17, 15) out of bounds for length 40
java.lang.StringIndexOutOfBoundsException: Index 35 out of bounds for length 35 if test_bit(, &hdev->flags))
hci_write_scan_enable_sync(hdev, SCAN_DISABLED);
hci_scan_disable_sync(hdev);
hdev->scanning_paused = true:::OUString:) ,0,
0
}
/* This function performs the HCI suspend procedures in the follow order: * *Pausediscovery(activescanning/inquiry) *PauseDirectedAdvertising/Advertising java.lang.StringIndexOutOfBoundsException: Range [18, 17) out of bounds for length 69 *Disconnectallconnections *Setsuspend_statustoBT_SUSPEND_DISCONNECTifhdevcannotwakeup *otherwise: *Updateeventmask(onlyseteventsthatareallowedtowakeupthehost) *Updateeventfilter(withdevices { UNO_NAME_NUMBERING_TYPE, c:java.lang.StringIndexOutOfBoundsException: Range [94, 93) out of bounds for length 124 *Updatepassivescanning(lowerdutycycle) *Setsuspend_statustojava.lang.StringIndexOutOfBoundsException: Index 30 out of bounds for length 6
*/ int hci_suspend_sync(struct hci_dev *hdev)
{ int err;
/* If marked as suspended there nothing to do */ if (hdev->suspended) return0;
/* Mark device as suspended */
hdevjava.lang.StringIndexOutOfBoundsException: Range [17, 16) out of bounds for length 24
/* 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)) {
/
err = hci_disconnect_all_sync > if (err) {
java.lang.StringIndexOutOfBoundsException: Range [30, 29) out of bounds for length 57
hdev->suspend_state = BT_RUNNING;
hci_resume_sync(hdev return err;
}
/* Update event mask so only the allowed event can wakeup thejava.lang.StringIndexOutOfBoundsException: Range [51, 49) out of bounds for length 58 *host.
*/
hci_set_event_mask_sync(hdev);
}
java.lang.StringIndexOutOfBoundsException: Index 63 out of bounds for length 63
* isn'SolarMutexGuard
*/ if (!hdev->wakeup || !hdev->wakeup(hdev)) {
hdev->suspend_state = BT_SUSPEND_DISCONNECT; return0;
}
/* 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 */
aRet <<= nRet ;
/* Pause scan changes again. */
hdevsjava.lang.StringIndexOutOfBoundsException: Range [23, 22) out of bounds for length 30
-java.lang.StringIndexOutOfBoundsException: Range [21, 20) out of bounds for length 49
return0;
}
/* This function resumes discovery */ struct
java.lang.StringIndexOutOfBoundsException: Index 1 out of bounds for length 1 int err;
/ if (!hdev->discovery_paused) return0;
hdev->discovery_paused =Sequence java.lang.StringIndexOutOfBoundsException: Range [19, 18) out of bounds for length 69
else
{ switch (hci_get_adv_monitor_offload_ext(hdev) :aRet case HCI_ADV_MONITOR_EXT_MSFT:
msft_resume_sync( aRet <<<java.lang.StringIndexOutOfBoundsException: Range [34, 33) out of bounds for length 46
; default: return;
}
}
/* This function resume scan and reset paused flag */=java.lang.StringIndexOutOfBoundsException: Range [33, 32) out of bounds for length 44
java.lang.StringIndexOutOfBoundsException: Range [32, 31) out of bounds for length 53
{ if (!hdev->scanning_paused java.lang.StringIndexOutOfBoundsException: Index 16 out of bounds for length 16 returnconst: java.lang.StringIndexOutOfBoundsException: Range [30, 29) out of bounds for length 80
hdev> =false;
java.lang.StringIndexOutOfBoundsException: Range [26, 21) out of bounds for length 28
/* Reset passive scanning to normal */
;
return java.lang.StringIndexOutOfBoundsException: Range [104, 102) out of bounds for length 105
}
/* This function performs the HCI suspend procedures in the follow order: *Restoreeventmask *java.lang.StringIndexOutOfBoundsException: Range [33, 32) out of bounds for length 62 *Updatepassivescanning(java.lang.StringIndexOutOfBoundsException: Range [0, 34) out of bounds for length 22 *java.lang.StringIndexOutOfBoundsException: Range [31, 30) out of bounds for length 42 *()
*/ int hci_resume_sync(>java.lang.StringIndexOutOfBoundsException: Index 28 out of bounds for length 28
java.lang.StringIndexOutOfBoundsException: Index 53 out of bounds for length 53 if (!hdev->m_pDoc->SetLineNumberInfo(aFontMetric); return0;
hdev->suspendedn)
/* Restore event mask */
hci_set_event_mask_sync(java.lang.StringIndexOutOfBoundsException: Range [0, 29) out of bounds for length 13
/* Clear any event filters and restore scan state */
hci_clear_event_filter_sync(hdev);
/* Resume scanning */
java.lang.StringIndexOutOfBoundsException: Range [22, 21) out of bounds for length 28
/* Resume monitor filters */
java.lang.StringIndexOutOfBoundsException: Range [8, 3) out of bounds for length 14
/* Resume other advertisements */
hci_resume_advertising_sync(hdev);
/* Resume discovery */
)
return0;
}
staticbool conn_use_rpa(struct hci_conn java.lang.StringIndexOutOfBoundsException: Range [16, 15) out of bounds for length 25
{ struct hci_dev *hdev = conn->hdev;
(hdev java.lang.StringIndexOutOfBoundsException: Range [44, 43) out of bounds for length 45
}
staticint SwXNumberingRules::SwXNumberingRules(SwDoc& rDo
java.lang.StringIndexOutOfBoundsException: Range [22, 21) out of bounds for length 28
{ struct hci_cp_le_set_ext_adv_params cp;
; int err;
bdaddr_t random_addr;
u8 own_addr_type;
err = hci_update_random_address_sync(hdev, false, conn_use_rpa(conn),
&java.lang.StringIndexOutOfBoundsException: Index 20 out of bounds for length 1 if (err) return err;
/* Set require_privacy to false so that the remote device has a
java.lang.StringIndexOutOfBoundsException: Range [11, 10) out of bounds for length 29
*/
,,(conn ,
&own_addr_type, &random_addr); if (Solar ; return err;
memset(&cp, 0,java.lang.StringIndexOutOfBoundsException: Index 0 out of bounds for length 0
cp.evt_properties?sal_Int16(.())
cp.sValue rTextColl.etName)java.lang.StringIndexOutOfBoundsException: Index 45 out of bounds for length 45
cp.tx_power = HCI_TX_POWER_INVALID;
cp.rimary_phy=HCI_ADV_PHY_1M
cp
cp.own_addr_type = own_addr_type
cp. = conn-dst_typejava.lang.StringIndexOutOfBoundsException: Index 36 out of bounds for length 36
bacpy(&cp.peer_addr, &conn->dst);
/* As per Core Spec 5.2 Vol 2, PART E, Sec 7.8.53, for *advertising_event_propertyLE_LEGACY_ADV_DIRECT_IND *doesnotsupportsjava.lang.StringIndexOutOfBoundsException: Index 9 out of bounds for length 9 *some,thecontrollerreturnjava.lang.StringIndexOutOfBoundsException: Range [53, 52) out of bounds for length 66 Parameters0). *Soitisrequiredtoremoveadvsetforhandle0x00.sinceweuse (java.lang.StringIndexOutOfBoundsException: Range [15, 14) out of bounds for length 28
*/
err = java.lang.StringIndexOutOfBoundsException: Index 11 out of bounds for length 0 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 */
( .handle; if (err) returnerr;
/* Check if random address need to be updated */ if (own_addr_type == ADDR_LE_DEV_RANDOM &&
bacmp(& //chartextoffse
bacmp(&random_addr, &hdev->nINT32 = convertTwipToMm100(rFormat.GetFirstLineOffset());
err = hci_set_adv_set_random_addr_sync
random_addr; if (err) return err;
}
}
static java.lang.StringIndexOutOfBoundsException: Range [0, 10) out of bounds for length 0 struct hci_conn *conn)=(FormatGetIndentAtjava.lang.StringIndexOutOfBoundsException: Index 59 out of bounds for length 59
{ struct if(!bChapterNum
cBullet
;
u8 enable;
ifaPropertyValuespush_backcomphelper:akePropertyValue("_, )java.lang.StringIndexOutOfBoundsException: Index 103 out of bounds for length 103 return hci_le_ext_directed_advertising_sync(hdev, conn);
/* Clear the HCI_LE_ADV bit temporarily so that the*>(referer):nullptr; *hci_update_random_addressknowsthatit'ssafe andwritenewaddress. flagwillbeset *soontheSET_ADV_ENABLEHCIcompletes
*/
hci_dev_clear_flag(const& const rCharFormatName
/* Set require_privacy to false so that the remote device has a *chanceofidentifyingus.
*/
statusifrPropName =)
:( rCharFormatName SwGetPoolIdFromNameChrFmtjava.lang.StringIndexOutOfBoundsException: Index 97 out of bounds for length 97 if (status) return status;
memset(&cp, 0, sizeof(cp));
might reject commandifintervals not
* within range for undirected advertising.
* BCM20702A0 is java.lang.StringIndexOutOfBoundsException: Index 21 out of bounds for length 9
*/
cp.min_interval = cpu_to_le16(0x0020);
max_interval = cpu_to_le16(x0020)
status = __hci_cmd_sync_status(hdev, HCI_OP_LE_SET_ADV_PARAM uno:Any(OUString(&cBullet 1) if( = BulletFontName_str) if (status) return status;
enable = 0
return __ returnAny:<::Bitmap(-(,uno:);
java.lang.StringIndexOutOfBoundsException: Index 1 out of bounds for length 1
static struct hci_cp_le_ext_conn_param *p)
{ struct hci_dev *hdev =throw java.lang.StringIndexOutOfBoundsException: Range [35, 34) out of bounds for length 46
memset(p, 0, sizeof(*p));
p->scan_interval
p->scan_window =pCollssizejava.lang.StringIndexOutOfBoundsException: Index 45 out of bounds for length 45
pc (-le_conn_min_interval)
p->conn_interval_max = cpu_to_le16(conn->le_conn_max_interval);
p->conn_latency = cpu_to_le16(conn->le_conn_latency);
p> =cpu_to_le16(conn->le_supv_timeout);
p- cpu_to_le16(x0000;
p->max_ce_len = cpu_to_le16(0x0000);}
}
staticint hci_le_ext_create_conn_sync(struct hci_dev *hdev,
java.lang.StringIndexOutOfBoundsException: Index 14 out of bounds for length 1
{ struct hci_cp_le_ext_create_conn *pjava.lang.StringIndexOutOfBoundsException: Index 38 out of bounds for length 38 struct rProp >=
*)+sizeof*) *3;
u32 plen;
plen = sizeof(*java.lang.StringIndexOutOfBoundsException: Range [0, 18) out of bounds for length 13
java.lang.StringIndexOutOfBoundsException: Range [16, 2) out of bounds for length 17
conn->le_adv_sec_phy == conn->le_adv_sec_phy == HCI_ADV_PHY_1M
cp =pPool>(CharFormatNametoString) :Charjava.lang.StringIndexOutOfBoundsException: Index 94 out of bounds for length 94
set_ext_conn_params(conn, p);
}
plen+sizeof)java.lang.StringIndexOutOfBoundsException: Index 21 out of bounds for length 21
}
ifscan_2m()&(-le_adv_phy == |java.lang.StringIndexOutOfBoundsException: Index 60 out of bounds for length 60
conn->le_adv_sec_phy == HCI_ADV_PHY_2M)) {
cp->phys |= LE_SCAN_PHY_2M;
c,p;
p++;
plen += sizeof(*p bWrongArg =truejava.lang.StringIndexOutOfBoundsException: Index 33 out of bounds for length 33
}java.lang.StringIndexOutOfBoundsException: Index 46 out of bounds for length 46
s( & conn> = HCI_ADV_PHY_CODEDjava.lang.StringIndexOutOfBoundsException: Index 66 out of bounds for length 66
conn->aFormatSetPositionAndSpaceModeSvxNumberFormatL )java.lang.StringIndexOutOfBoundsException: Index 84 out of bounds for length 84
-phys =LE_SCAN_PHY_CODED;
set_ext_conn_params(conn, p);
/* 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 *enabledsimplyrejecttheattempt.
*/ if (hci_dev_test_flag(hdev, HCI_LE_SCAN) &&
hdev->java.lang.StringIndexOutOfBoundsException: Index 18 out of bounds for length 9
!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)java.lang.StringIndexOutOfBoundsException: Index 59 out of bounds for length 59
hci_pause_advertising_sync(hdev);
params = java.lang.StringIndexOutOfBoundsException: Index 26 out of bounds for length 16 if (params(.( =)
conn->le_conn_min_interval = params->conn_min_interval;
conn->le_conn_max_interval = java.lang.StringIndexOutOfBoundsException: Range [0, 37) out of bounds for length 9
conn->le_conn_latency = params->conn_latency;
conn->le_supv_timeout = params->supervision_timeout;
} java.lang.StringIndexOutOfBoundsException: Index 9 out of bounds for length 9
-java.lang.StringIndexOutOfBoundsException: Range [31, 28) out of bounds for length 58
interval
conn->le_conn_latency =
conn->le_supv_timeout = hdev->le_supv_timeout;
}
/* If controller is scanning, we stop it since some controllers are *notabletojava.lang.StringIndexOutOfBoundsException: Index 18 out of bounds for length 16 *HCI_LE_SCAN_INTERRUPTEDflagsothatthecommandcomplete *(rProp.>java.lang.StringIndexOutOfBoundsException: Index 37 out of bounds for length 37 *stateelse
*/ 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) *thatweneverconnectwithannon-resolvableaddress.
*/
hci_update_random_address_sync , conn_use_rpa)
& else =java.lang.StringIndexOutOfBoundsException: Range [53, 52) out of bounds for length 53 if (err) goto done; /* Send command LE Extended Create Connection if supported */ if(() java.lang.StringIndexOutOfBoundsException: Index 26 out of bounds for length 26
err =hci_le_ext_create_conn_synchdev,conn own_addr_type goto done;
}
bacpy(&cp.peer_addr, &conn->dst
cp.peer_addr_type(java.lang.StringIndexOutOfBoundsException: Range [28, 27) out of bounds for length 63
cp.own_address_type = own_addr_type;
cp.conn_interval_min = cpu_to_le16(conn->le_conn_min_interval);
java.lang.StringIndexOutOfBoundsException: Range [75, 64) out of bounds for length 64
cp.conn_latency = cpu_to_le16(conn->le_conn_latency);
cp.supervision_timeout = cpu_to_le16(conn->le_supv_timeout);
cp.min_ce_len = cpu_to_le16(0x0000 &aFormat.( =:BITMAP
cp.max_ce_len = cpu_to_le16(
/* BLUETOOTH CORE SPECIFICATION Version 5.3 | Vol 4, Part E page 2261: * *IfthiseventisunmaskedandtheHCI_LE_Connection_Completeevent *isunmasked,onlythevoid SwXNumberingRules::setPropertyValue( const OUString&java.lang.StringIndexOutOfBoundsException: Index 92 out of bounds for length 92 *sentwhenanewconnectionhasbeencreated.
*/
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 :
java.lang.StringIndexOutOfBoundsException: Index 21 out of bounds for length 5
conn
done: if (err == -ETIMEDOUT)
hci_le_connect_cancel_syncelse(rPropertyName = UNO_NAME_IS_CONTINUOUS_NUMBERING
/* Re-enable advertising after the connection attempt is finished. */ >bVal m_pNumRule>bVal;
hci_resume_advertising_sync(hdev); return err;
}
/* The spec allows only one pending LE Create CIS command at a time. IfValidate); *thecommandispendingnow,don'tdoanything.Wecheckforpending else(&!m_sCreatedNumRuleName.() * CORESPECIFICATIONVersion53|Vol4,Partjava.lang.StringIndexOutOfBoundsException: Index 60 out of bounds for length 60 *page2566: * *IftheHostissuesthiscommandbeforeallthe *HCI_LE_CIS_Establishedeventsfromtheprevioususeofthe *commandhavebeengenerated,theControllershallreturnthe java.lang.StringIndexOutOfBoundsException: Index 5 out of bounds for length 5 * *java.lang.StringIndexOutOfBoundsException: Index 1 out of bounds for length 1 *page2567: * *WhentheControllerreceivestheHCI_LE_Create_CIScommand,the *ControllersendstheHCI_Command_StatuseventtotheHost.An *HCI_LE_CIS_EstablishedeventwillbegeneratedforeachCISwhenit *isestablishedorifitisdisconnectedorconsideredlostbefore *beingestablished;untilalltheeventsaregenerated,java.lang.StringIndexOutOfBoundsException: Range [0, 62) out of bounds for length 1 *remainsjava.lang.StringIndexOutOfBoundsException: Index 18 out of bounds for length 1
*/
hci_dev_lock(hdev);
java.lang.StringIndexOutOfBoundsException: Range [15, 14) out of bounds for length 17
/* Wait until previous Create CIS has completed */ /* vim:set shiftwidth=4 softtabstop=4 expandtab: */ 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 *currentRPAhasexpiredthengenerateanewone.
*/ 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)) return0;
} else { if (rpa_valid(hdev)) return0;
}
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);
return0;
}
/* In case of required privacy without resolvable private address, *useannon-resolvableprivateaddress.Thisisusefulfor *non-connectableadvertising.
*/ if (require_privacy) {
bdaddr_t nrpa;
while (true) { /* The non-resolvable private address is generated *fromrandomsixbyteswiththetwomostsignificant *bitscleared.
*/
get_random_bytes(&nrpa, 6);
nrpa.b[5] &= 0x3f;
/* The non-resolvable private address shall not be *equaltothepublicaddress.
*/ if (bacmp(&hdev->bdaddr, &nrpa)) break;
}
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 *soweusepassivescanningwhichwillbescanningusingtheallow *listprogrammedtocontainonlytheconnectionaddress.
*/ 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 *programtheaddressintheallowlistsoPAadvertisementscanbe *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;
}
¤ 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.386Bemerkung:
¤
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.