#include <net/bluetooth/l2cap.h>
#include <net/bluetooth/mgmt.h>
+#include "hci_request.h"
#include "smp.h"
#define MGMT_VERSION 1
* entries.
*/
hci_req_init(&req, hdev);
- hci_update_page_scan(hdev, &req);
+ __hci_update_page_scan(&req);
update_class(&req);
hci_req_run(&req, NULL);
if (conn_changed || discov_changed) {
new_settings(hdev, cmd->sk);
- hci_update_page_scan(hdev, NULL);
+ hci_update_page_scan(hdev);
if (discov_changed)
mgmt_update_adv_data(hdev);
hci_update_background_scan(hdev);
return err;
if (changed) {
- hci_update_page_scan(hdev, NULL);
+ hci_update_page_scan(hdev);
hci_update_background_scan(hdev);
return new_settings(hdev, sk);
}
hci_req_init(&req, hdev);
write_fast_connectable(&req, false);
- hci_update_page_scan(hdev, &req);
+ __hci_update_page_scan(&req);
/* Since only the advertising data flags will change, there
* is no need to update the scan response data.
if (err)
goto unlock;
- hci_update_page_scan(hdev, NULL);
+ hci_update_page_scan(hdev);
goto added;
}
goto unlock;
}
- hci_update_page_scan(hdev, NULL);
+ hci_update_page_scan(hdev);
device_removed(sk, hdev, &cp->addr.bdaddr,
cp->addr.type);
kfree(b);
}
- hci_update_page_scan(hdev, NULL);
+ hci_update_page_scan(hdev);
list_for_each_entry_safe(p, tmp, &hdev->le_conn_params, list) {
if (p->auto_connect == HCI_AUTO_CONN_DISABLED)
if (!buf)
return -ENOMEM;
- if (memcpy_fromiovec(buf, msg->msg_iov, msglen)) {
+ if (memcpy_from_msg(buf, msg, msglen)) {
err = -EFAULT;
goto done;
}
hci_req_add(&req, HCI_OP_WRITE_SSP_MODE, 1, &ssp);
}
+ if (bredr_sc_enabled(hdev) && !lmp_host_sc_capable(hdev)) {
+ u8 sc = 0x01;
+ hci_req_add(&req, HCI_OP_WRITE_SC_SUPPORT, sizeof(sc), &sc);
+ }
+
if (test_bit(HCI_LE_ENABLED, &hdev->dev_flags) &&
lmp_bredr_capable(hdev)) {
struct hci_cp_write_le_host_supported cp;
if (lmp_bredr_capable(hdev)) {
write_fast_connectable(&req, false);
- hci_update_page_scan(hdev, &req);
+ __hci_update_page_scan(&req);
update_class(&req);
update_name(&req);
update_eir(&req);
int mgmt_powered(struct hci_dev *hdev, u8 powered)
{
struct cmd_lookup match = { NULL, hdev };
- u8 status_not_powered = MGMT_STATUS_NOT_POWERED;
- u8 zero_cod[] = { 0, 0, 0 };
+ u8 status, zero_cod[] = { 0, 0, 0 };
int err;
if (!test_bit(HCI_MGMT, &hdev->dev_flags))
}
mgmt_pending_foreach(MGMT_OP_SET_POWERED, hdev, settings_rsp, &match);
- mgmt_pending_foreach(0, hdev, cmd_complete_rsp, &status_not_powered);
+
+ /* If the power off is because of hdev unregistration let
+ * use the appropriate INVALID_INDEX status. Otherwise use
+ * NOT_POWERED. We cover both scenarios here since later in
+ * mgmt_index_removed() any hci_conn callbacks will have already
+ * been triggered, potentially causing misleading DISCONNECTED
+ * status responses.
+ */
+ if (test_bit(HCI_UNREGISTER, &hdev->dev_flags))
+ status = MGMT_STATUS_INVALID_INDEX;
+ else
+ status = MGMT_STATUS_NOT_POWERED;
+
+ mgmt_pending_foreach(0, hdev, cmd_complete_rsp, &status);
if (memcmp(hdev->dev_class, zero_cod, sizeof(zero_cod)) != 0)
mgmt_event(MGMT_EV_CLASS_OF_DEV_CHANGED, hdev,
* kept and checking possible scan response data
* will be skipped.
*/
- if (hdev->discovery.uuid_count > 0) {
+ if (hdev->discovery.uuid_count > 0)
match = eir_has_uuids(eir, eir_len,
hdev->discovery.uuid_count,
hdev->discovery.uuids);
- if (!match)
- return;
- }
+ else
+ match = true;
+
+ if (!match && !scan_rsp_len)
+ return;
/* Copy EIR or advertising data into event */
memcpy(ev->eir, eir, eir_len);
* provided, results with empty EIR or advertising data
* should be dropped since they do not match any UUID.
*/
- if (hdev->discovery.uuid_count > 0)
+ if (hdev->discovery.uuid_count > 0 && !scan_rsp_len)
return;
+
+ match = false;
}
if (dev_class && !eir_has_data_type(ev->eir, eir_len, EIR_CLASS_OF_DEV))