Loading net/bluetooth/mgmt.c +85 −65 Original line number Diff line number Diff line Loading @@ -3921,55 +3921,50 @@ static int remove_remote_oob_data(struct sock *sk, struct hci_dev *hdev, return err; } static bool trigger_discovery(struct hci_request *req, u8 *status) static bool trigger_bredr_inquiry(struct hci_request *req, u8 *status) { struct hci_dev *hdev = req->hdev; struct hci_cp_le_set_scan_param param_cp; struct hci_cp_le_set_scan_enable enable_cp; struct hci_cp_inquiry inq_cp; struct hci_cp_inquiry cp; /* General inquiry access code (GIAC) */ u8 lap[3] = { 0x33, 0x8b, 0x9e }; u8 own_addr_type; int err; switch (hdev->discovery.type) { case DISCOV_TYPE_BREDR: *status = mgmt_bredr_support(hdev); if (*status) return false; if (test_bit(HCI_INQUIRY, &hdev->flags)) { if (hci_dev_test_flag(hdev, HCI_INQUIRY)) { *status = MGMT_STATUS_BUSY; return false; } hci_inquiry_cache_flush(hdev); memset(&inq_cp, 0, sizeof(inq_cp)); memcpy(&inq_cp.lap, lap, sizeof(inq_cp.lap)); inq_cp.length = DISCOV_BREDR_INQUIRY_LEN; hci_req_add(req, HCI_OP_INQUIRY, sizeof(inq_cp), &inq_cp); break; memset(&cp, 0, sizeof(cp)); memcpy(&cp.lap, lap, sizeof(cp.lap)); cp.length = DISCOV_BREDR_INQUIRY_LEN; hci_req_add(req, HCI_OP_INQUIRY, sizeof(cp), &cp); return true; } static bool trigger_le_scan(struct hci_request *req, u16 interval, u8 *status) { struct hci_dev *hdev = req->hdev; struct hci_cp_le_set_scan_param param_cp; struct hci_cp_le_set_scan_enable enable_cp; u8 own_addr_type; int err; case DISCOV_TYPE_LE: case DISCOV_TYPE_INTERLEAVED: *status = mgmt_le_support(hdev); if (*status) return false; if (hdev->discovery.type == DISCOV_TYPE_INTERLEAVED && !hci_dev_test_flag(hdev, HCI_BREDR_ENABLED)) { *status = MGMT_STATUS_NOT_SUPPORTED; return false; } if (hci_dev_test_flag(hdev, HCI_LE_ADV)) { /* Don't let discovery abort an outgoing * connection attempt that's using directed * advertising. /* Don't let discovery abort an outgoing connection attempt * that's using directed advertising. */ if (hci_conn_hash_lookup_state(hdev, LE_LINK, BT_CONNECT)) { if (hci_conn_hash_lookup_state(hdev, LE_LINK, BT_CONNECT)) { *status = MGMT_STATUS_REJECTED; return false; } Loading @@ -3977,18 +3972,16 @@ static bool trigger_discovery(struct hci_request *req, u8 *status) disable_advertising(req); } /* If controller is scanning, it means the background scanning * is running. Thus, we should temporarily stop it in order to * set the discovery scanning parameters. /* If controller is scanning, it means the background scanning is * running. Thus, we should temporarily stop it in order to set the * discovery scanning parameters. */ if (hci_dev_test_flag(hdev, HCI_LE_SCAN)) hci_req_add_le_scan_disable(req); memset(¶m_cp, 0, sizeof(param_cp)); /* All active scans will be done with either a resolvable * private address (when privacy feature has been enabled) * or non-resolvable private address. /* 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(req, true, &own_addr_type); if (err < 0) { Loading @@ -3996,18 +3989,45 @@ static bool trigger_discovery(struct hci_request *req, u8 *status) return false; } memset(¶m_cp, 0, sizeof(param_cp)); param_cp.type = LE_SCAN_ACTIVE; param_cp.interval = cpu_to_le16(DISCOV_LE_SCAN_INT); param_cp.interval = cpu_to_le16(interval); param_cp.window = cpu_to_le16(DISCOV_LE_SCAN_WIN); param_cp.own_address_type = own_addr_type; hci_req_add(req, HCI_OP_LE_SET_SCAN_PARAM, sizeof(param_cp), ¶m_cp); memset(&enable_cp, 0, sizeof(enable_cp)); enable_cp.enable = LE_SCAN_ENABLE; enable_cp.filter_dup = LE_SCAN_FILTER_DUP_ENABLE; hci_req_add(req, HCI_OP_LE_SET_SCAN_ENABLE, sizeof(enable_cp), &enable_cp); return true; } static bool trigger_discovery(struct hci_request *req, u8 *status) { struct hci_dev *hdev = req->hdev; switch (hdev->discovery.type) { case DISCOV_TYPE_BREDR: if (!trigger_bredr_inquiry(req, status)) return false; break; case DISCOV_TYPE_INTERLEAVED: if (!hci_dev_test_flag(hdev, HCI_BREDR_ENABLED)) { *status = MGMT_STATUS_NOT_SUPPORTED; return false; } /* fall through */ case DISCOV_TYPE_LE: if (!trigger_le_scan(req, DISCOV_LE_SCAN_INT, status)) return false; break; default: Loading Loading
net/bluetooth/mgmt.c +85 −65 Original line number Diff line number Diff line Loading @@ -3921,55 +3921,50 @@ static int remove_remote_oob_data(struct sock *sk, struct hci_dev *hdev, return err; } static bool trigger_discovery(struct hci_request *req, u8 *status) static bool trigger_bredr_inquiry(struct hci_request *req, u8 *status) { struct hci_dev *hdev = req->hdev; struct hci_cp_le_set_scan_param param_cp; struct hci_cp_le_set_scan_enable enable_cp; struct hci_cp_inquiry inq_cp; struct hci_cp_inquiry cp; /* General inquiry access code (GIAC) */ u8 lap[3] = { 0x33, 0x8b, 0x9e }; u8 own_addr_type; int err; switch (hdev->discovery.type) { case DISCOV_TYPE_BREDR: *status = mgmt_bredr_support(hdev); if (*status) return false; if (test_bit(HCI_INQUIRY, &hdev->flags)) { if (hci_dev_test_flag(hdev, HCI_INQUIRY)) { *status = MGMT_STATUS_BUSY; return false; } hci_inquiry_cache_flush(hdev); memset(&inq_cp, 0, sizeof(inq_cp)); memcpy(&inq_cp.lap, lap, sizeof(inq_cp.lap)); inq_cp.length = DISCOV_BREDR_INQUIRY_LEN; hci_req_add(req, HCI_OP_INQUIRY, sizeof(inq_cp), &inq_cp); break; memset(&cp, 0, sizeof(cp)); memcpy(&cp.lap, lap, sizeof(cp.lap)); cp.length = DISCOV_BREDR_INQUIRY_LEN; hci_req_add(req, HCI_OP_INQUIRY, sizeof(cp), &cp); return true; } static bool trigger_le_scan(struct hci_request *req, u16 interval, u8 *status) { struct hci_dev *hdev = req->hdev; struct hci_cp_le_set_scan_param param_cp; struct hci_cp_le_set_scan_enable enable_cp; u8 own_addr_type; int err; case DISCOV_TYPE_LE: case DISCOV_TYPE_INTERLEAVED: *status = mgmt_le_support(hdev); if (*status) return false; if (hdev->discovery.type == DISCOV_TYPE_INTERLEAVED && !hci_dev_test_flag(hdev, HCI_BREDR_ENABLED)) { *status = MGMT_STATUS_NOT_SUPPORTED; return false; } if (hci_dev_test_flag(hdev, HCI_LE_ADV)) { /* Don't let discovery abort an outgoing * connection attempt that's using directed * advertising. /* Don't let discovery abort an outgoing connection attempt * that's using directed advertising. */ if (hci_conn_hash_lookup_state(hdev, LE_LINK, BT_CONNECT)) { if (hci_conn_hash_lookup_state(hdev, LE_LINK, BT_CONNECT)) { *status = MGMT_STATUS_REJECTED; return false; } Loading @@ -3977,18 +3972,16 @@ static bool trigger_discovery(struct hci_request *req, u8 *status) disable_advertising(req); } /* If controller is scanning, it means the background scanning * is running. Thus, we should temporarily stop it in order to * set the discovery scanning parameters. /* If controller is scanning, it means the background scanning is * running. Thus, we should temporarily stop it in order to set the * discovery scanning parameters. */ if (hci_dev_test_flag(hdev, HCI_LE_SCAN)) hci_req_add_le_scan_disable(req); memset(¶m_cp, 0, sizeof(param_cp)); /* All active scans will be done with either a resolvable * private address (when privacy feature has been enabled) * or non-resolvable private address. /* 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(req, true, &own_addr_type); if (err < 0) { Loading @@ -3996,18 +3989,45 @@ static bool trigger_discovery(struct hci_request *req, u8 *status) return false; } memset(¶m_cp, 0, sizeof(param_cp)); param_cp.type = LE_SCAN_ACTIVE; param_cp.interval = cpu_to_le16(DISCOV_LE_SCAN_INT); param_cp.interval = cpu_to_le16(interval); param_cp.window = cpu_to_le16(DISCOV_LE_SCAN_WIN); param_cp.own_address_type = own_addr_type; hci_req_add(req, HCI_OP_LE_SET_SCAN_PARAM, sizeof(param_cp), ¶m_cp); memset(&enable_cp, 0, sizeof(enable_cp)); enable_cp.enable = LE_SCAN_ENABLE; enable_cp.filter_dup = LE_SCAN_FILTER_DUP_ENABLE; hci_req_add(req, HCI_OP_LE_SET_SCAN_ENABLE, sizeof(enable_cp), &enable_cp); return true; } static bool trigger_discovery(struct hci_request *req, u8 *status) { struct hci_dev *hdev = req->hdev; switch (hdev->discovery.type) { case DISCOV_TYPE_BREDR: if (!trigger_bredr_inquiry(req, status)) return false; break; case DISCOV_TYPE_INTERLEAVED: if (!hci_dev_test_flag(hdev, HCI_BREDR_ENABLED)) { *status = MGMT_STATUS_NOT_SUPPORTED; return false; } /* fall through */ case DISCOV_TYPE_LE: if (!trigger_le_scan(req, DISCOV_LE_SCAN_INT, status)) return false; break; default: Loading