aboutsummaryrefslogtreecommitdiffstats
path: root/net/bluetooth/mgmt.c
diff options
context:
space:
mode:
Diffstat (limited to 'net/bluetooth/mgmt.c')
-rw-r--r--net/bluetooth/mgmt.c124
1 files changed, 40 insertions, 84 deletions
diff --git a/net/bluetooth/mgmt.c b/net/bluetooth/mgmt.c
index b8554d429d88..c2457435a670 100644
--- a/net/bluetooth/mgmt.c
+++ b/net/bluetooth/mgmt.c
@@ -129,9 +129,6 @@ static const u16 mgmt_events[] = {
129 129
130#define CACHE_TIMEOUT msecs_to_jiffies(2 * 1000) 130#define CACHE_TIMEOUT msecs_to_jiffies(2 * 1000)
131 131
132#define hdev_is_powered(hdev) (test_bit(HCI_UP, &hdev->flags) && \
133 !test_bit(HCI_AUTO_OFF, &hdev->dev_flags))
134
135struct pending_cmd { 132struct pending_cmd {
136 struct list_head list; 133 struct list_head list;
137 u16 opcode; 134 u16 opcode;
@@ -1536,9 +1533,11 @@ static void set_discoverable_complete(struct hci_dev *hdev, u8 status)
1536 1533
1537 /* When the discoverable mode gets changed, make sure 1534 /* When the discoverable mode gets changed, make sure
1538 * that class of device has the limited discoverable 1535 * that class of device has the limited discoverable
1539 * bit correctly set. 1536 * bit correctly set. Also update page scan based on whitelist
1537 * entries.
1540 */ 1538 */
1541 hci_req_init(&req, hdev); 1539 hci_req_init(&req, hdev);
1540 hci_update_page_scan(hdev, &req);
1542 update_class(&req); 1541 update_class(&req);
1543 hci_req_run(&req, NULL); 1542 hci_req_run(&req, NULL);
1544 1543
@@ -1785,6 +1784,7 @@ static void set_connectable_complete(struct hci_dev *hdev, u8 status)
1785 1784
1786 if (conn_changed || discov_changed) { 1785 if (conn_changed || discov_changed) {
1787 new_settings(hdev, cmd->sk); 1786 new_settings(hdev, cmd->sk);
1787 hci_update_page_scan(hdev, NULL);
1788 if (discov_changed) 1788 if (discov_changed)
1789 mgmt_update_adv_data(hdev); 1789 mgmt_update_adv_data(hdev);
1790 hci_update_background_scan(hdev); 1790 hci_update_background_scan(hdev);
@@ -1818,6 +1818,7 @@ static int set_connectable_update_settings(struct hci_dev *hdev,
1818 return err; 1818 return err;
1819 1819
1820 if (changed) { 1820 if (changed) {
1821 hci_update_page_scan(hdev, NULL);
1821 hci_update_background_scan(hdev); 1822 hci_update_background_scan(hdev);
1822 return new_settings(hdev, sk); 1823 return new_settings(hdev, sk);
1823 } 1824 }
@@ -4381,27 +4382,6 @@ unlock:
4381 return err; 4382 return err;
4382} 4383}
4383 4384
4384static void set_bredr_scan(struct hci_request *req)
4385{
4386 struct hci_dev *hdev = req->hdev;
4387 u8 scan = 0;
4388
4389 /* Ensure that fast connectable is disabled. This function will
4390 * not do anything if the page scan parameters are already what
4391 * they should be.
4392 */
4393 write_fast_connectable(req, false);
4394
4395 if (test_bit(HCI_CONNECTABLE, &hdev->dev_flags) ||
4396 !list_empty(&hdev->whitelist))
4397 scan |= SCAN_PAGE;
4398 if (test_bit(HCI_DISCOVERABLE, &hdev->dev_flags))
4399 scan |= SCAN_INQUIRY;
4400
4401 if (scan)
4402 hci_req_add(req, HCI_OP_WRITE_SCAN_ENABLE, 1, &scan);
4403}
4404
4405static void set_bredr_complete(struct hci_dev *hdev, u8 status) 4385static void set_bredr_complete(struct hci_dev *hdev, u8 status)
4406{ 4386{
4407 struct pending_cmd *cmd; 4387 struct pending_cmd *cmd;
@@ -4507,9 +4487,8 @@ static int set_bredr(struct sock *sk, struct hci_dev *hdev, void *data, u16 len)
4507 4487
4508 hci_req_init(&req, hdev); 4488 hci_req_init(&req, hdev);
4509 4489
4510 if (test_bit(HCI_CONNECTABLE, &hdev->dev_flags) || 4490 write_fast_connectable(&req, false);
4511 !list_empty(&hdev->whitelist)) 4491 hci_update_page_scan(hdev, &req);
4512 set_bredr_scan(&req);
4513 4492
4514 /* Since only the advertising data flags will change, there 4493 /* Since only the advertising data flags will change, there
4515 * is no need to update the scan response data. 4494 * is no need to update the scan response data.
@@ -5235,27 +5214,6 @@ unlock:
5235 return err; 5214 return err;
5236} 5215}
5237 5216
5238/* Helper for Add/Remove Device commands */
5239static void update_page_scan(struct hci_dev *hdev, u8 scan)
5240{
5241 if (!test_bit(HCI_BREDR_ENABLED, &hdev->dev_flags))
5242 return;
5243
5244 if (!hdev_is_powered(hdev))
5245 return;
5246
5247 /* If HCI_CONNECTABLE is set then Add/Remove Device should not
5248 * make any changes to page scanning.
5249 */
5250 if (test_bit(HCI_CONNECTABLE, &hdev->dev_flags))
5251 return;
5252
5253 if (test_bit(HCI_DISCOVERABLE, &hdev->dev_flags))
5254 scan |= SCAN_INQUIRY;
5255
5256 hci_send_cmd(hdev, HCI_OP_WRITE_SCAN_ENABLE, 1, &scan);
5257}
5258
5259static void device_added(struct sock *sk, struct hci_dev *hdev, 5217static void device_added(struct sock *sk, struct hci_dev *hdev,
5260 bdaddr_t *bdaddr, u8 type, u8 action) 5218 bdaddr_t *bdaddr, u8 type, u8 action)
5261{ 5219{
@@ -5291,8 +5249,6 @@ static int add_device(struct sock *sk, struct hci_dev *hdev,
5291 hci_dev_lock(hdev); 5249 hci_dev_lock(hdev);
5292 5250
5293 if (cp->addr.type == BDADDR_BREDR) { 5251 if (cp->addr.type == BDADDR_BREDR) {
5294 bool update_scan;
5295
5296 /* Only incoming connections action is supported for now */ 5252 /* Only incoming connections action is supported for now */
5297 if (cp->action != 0x01) { 5253 if (cp->action != 0x01) {
5298 err = cmd_complete(sk, hdev->id, MGMT_OP_ADD_DEVICE, 5254 err = cmd_complete(sk, hdev->id, MGMT_OP_ADD_DEVICE,
@@ -5301,15 +5257,12 @@ static int add_device(struct sock *sk, struct hci_dev *hdev,
5301 goto unlock; 5257 goto unlock;
5302 } 5258 }
5303 5259
5304 update_scan = list_empty(&hdev->whitelist);
5305
5306 err = hci_bdaddr_list_add(&hdev->whitelist, &cp->addr.bdaddr, 5260 err = hci_bdaddr_list_add(&hdev->whitelist, &cp->addr.bdaddr,
5307 cp->addr.type); 5261 cp->addr.type);
5308 if (err) 5262 if (err)
5309 goto unlock; 5263 goto unlock;
5310 5264
5311 if (update_scan) 5265 hci_update_page_scan(hdev, NULL);
5312 update_page_scan(hdev, SCAN_PAGE);
5313 5266
5314 goto added; 5267 goto added;
5315 } 5268 }
@@ -5392,8 +5345,7 @@ static int remove_device(struct sock *sk, struct hci_dev *hdev,
5392 goto unlock; 5345 goto unlock;
5393 } 5346 }
5394 5347
5395 if (list_empty(&hdev->whitelist)) 5348 hci_update_page_scan(hdev, NULL);
5396 update_page_scan(hdev, SCAN_DISABLED);
5397 5349
5398 device_removed(sk, hdev, &cp->addr.bdaddr, 5350 device_removed(sk, hdev, &cp->addr.bdaddr,
5399 cp->addr.type); 5351 cp->addr.type);
@@ -5444,7 +5396,7 @@ static int remove_device(struct sock *sk, struct hci_dev *hdev,
5444 kfree(b); 5396 kfree(b);
5445 } 5397 }
5446 5398
5447 update_page_scan(hdev, SCAN_DISABLED); 5399 hci_update_page_scan(hdev, NULL);
5448 5400
5449 list_for_each_entry_safe(p, tmp, &hdev->le_conn_params, list) { 5401 list_for_each_entry_safe(p, tmp, &hdev->le_conn_params, list) {
5450 if (p->auto_connect == HCI_AUTO_CONN_DISABLED) 5402 if (p->auto_connect == HCI_AUTO_CONN_DISABLED)
@@ -5969,8 +5921,8 @@ static int powered_update_hci(struct hci_dev *hdev)
5969 sizeof(link_sec), &link_sec); 5921 sizeof(link_sec), &link_sec);
5970 5922
5971 if (lmp_bredr_capable(hdev)) { 5923 if (lmp_bredr_capable(hdev)) {
5972 if (test_bit(HCI_BREDR_ENABLED, &hdev->dev_flags)) 5924 write_fast_connectable(&req, false);
5973 set_bredr_scan(&req); 5925 hci_update_page_scan(hdev, &req);
5974 update_class(&req); 5926 update_class(&req);
5975 update_name(&req); 5927 update_name(&req);
5976 update_eir(&req); 5928 update_eir(&req);
@@ -6281,25 +6233,35 @@ static void unpair_device_rsp(struct pending_cmd *cmd, void *data)
6281 mgmt_pending_remove(cmd); 6233 mgmt_pending_remove(cmd);
6282} 6234}
6283 6235
6236bool mgmt_powering_down(struct hci_dev *hdev)
6237{
6238 struct pending_cmd *cmd;
6239 struct mgmt_mode *cp;
6240
6241 cmd = mgmt_pending_find(MGMT_OP_SET_POWERED, hdev);
6242 if (!cmd)
6243 return false;
6244
6245 cp = cmd->param;
6246 if (!cp->val)
6247 return true;
6248
6249 return false;
6250}
6251
6284void mgmt_device_disconnected(struct hci_dev *hdev, bdaddr_t *bdaddr, 6252void mgmt_device_disconnected(struct hci_dev *hdev, bdaddr_t *bdaddr,
6285 u8 link_type, u8 addr_type, u8 reason, 6253 u8 link_type, u8 addr_type, u8 reason,
6286 bool mgmt_connected) 6254 bool mgmt_connected)
6287{ 6255{
6288 struct mgmt_ev_device_disconnected ev; 6256 struct mgmt_ev_device_disconnected ev;
6289 struct pending_cmd *power_off;
6290 struct sock *sk = NULL; 6257 struct sock *sk = NULL;
6291 6258
6292 power_off = mgmt_pending_find(MGMT_OP_SET_POWERED, hdev); 6259 /* The connection is still in hci_conn_hash so test for 1
6293 if (power_off) { 6260 * instead of 0 to know if this is the last one.
6294 struct mgmt_mode *cp = power_off->param; 6261 */
6295 6262 if (mgmt_powering_down(hdev) && hci_conn_count(hdev) == 1) {
6296 /* The connection is still in hci_conn_hash so test for 1 6263 cancel_delayed_work(&hdev->power_off);
6297 * instead of 0 to know if this is the last one. 6264 queue_work(hdev->req_workqueue, &hdev->power_off.work);
6298 */
6299 if (!cp->val && hci_conn_count(hdev) == 1) {
6300 cancel_delayed_work(&hdev->power_off);
6301 queue_work(hdev->req_workqueue, &hdev->power_off.work);
6302 }
6303 } 6265 }
6304 6266
6305 if (!mgmt_connected) 6267 if (!mgmt_connected)
@@ -6359,19 +6321,13 @@ void mgmt_connect_failed(struct hci_dev *hdev, bdaddr_t *bdaddr, u8 link_type,
6359 u8 addr_type, u8 status) 6321 u8 addr_type, u8 status)
6360{ 6322{
6361 struct mgmt_ev_connect_failed ev; 6323 struct mgmt_ev_connect_failed ev;
6362 struct pending_cmd *power_off;
6363
6364 power_off = mgmt_pending_find(MGMT_OP_SET_POWERED, hdev);
6365 if (power_off) {
6366 struct mgmt_mode *cp = power_off->param;
6367 6324
6368 /* The connection is still in hci_conn_hash so test for 1 6325 /* The connection is still in hci_conn_hash so test for 1
6369 * instead of 0 to know if this is the last one. 6326 * instead of 0 to know if this is the last one.
6370 */ 6327 */
6371 if (!cp->val && hci_conn_count(hdev) == 1) { 6328 if (mgmt_powering_down(hdev) && hci_conn_count(hdev) == 1) {
6372 cancel_delayed_work(&hdev->power_off); 6329 cancel_delayed_work(&hdev->power_off);
6373 queue_work(hdev->req_workqueue, &hdev->power_off.work); 6330 queue_work(hdev->req_workqueue, &hdev->power_off.work);
6374 }
6375 } 6331 }
6376 6332
6377 bacpy(&ev.addr.bdaddr, bdaddr); 6333 bacpy(&ev.addr.bdaddr, bdaddr);