.. | .. |
---|
367 | 367 | /* 160 msec page scan interval */ |
---|
368 | 368 | acp.interval = cpu_to_le16(0x0100); |
---|
369 | 369 | } else { |
---|
370 | | - type = PAGE_SCAN_TYPE_STANDARD; /* default */ |
---|
371 | | - |
---|
372 | | - /* default 1.28 sec page scan */ |
---|
373 | | - acp.interval = cpu_to_le16(0x0800); |
---|
| 370 | + type = hdev->def_page_scan_type; |
---|
| 371 | + acp.interval = cpu_to_le16(hdev->def_page_scan_int); |
---|
374 | 372 | } |
---|
375 | 373 | |
---|
376 | | - acp.window = cpu_to_le16(0x0012); |
---|
| 374 | + acp.window = cpu_to_le16(hdev->def_page_scan_window); |
---|
377 | 375 | |
---|
378 | 376 | if (__cpu_to_le16(hdev->page_scan_interval) != acp.interval || |
---|
379 | 377 | __cpu_to_le16(hdev->page_scan_window) != acp.window) |
---|
.. | .. |
---|
419 | 417 | */ |
---|
420 | 418 | hci_discovery_filter_clear(hdev); |
---|
421 | 419 | |
---|
| 420 | + BT_DBG("%s ADV monitoring is %s", hdev->name, |
---|
| 421 | + hci_is_adv_monitoring(hdev) ? "on" : "off"); |
---|
| 422 | + |
---|
422 | 423 | if (list_empty(&hdev->pend_le_conns) && |
---|
423 | | - list_empty(&hdev->pend_le_reports)) { |
---|
| 424 | + list_empty(&hdev->pend_le_reports) && |
---|
| 425 | + !hci_is_adv_monitoring(hdev)) { |
---|
424 | 426 | /* If there is no pending LE connections or devices |
---|
425 | | - * to be scanned for, we should stop the background |
---|
426 | | - * scanning. |
---|
| 427 | + * to be scanned for or no ADV monitors, we should stop the |
---|
| 428 | + * background scanning. |
---|
427 | 429 | */ |
---|
428 | 430 | |
---|
429 | 431 | /* If controller is not scanning we are done. */ |
---|
430 | 432 | if (!hci_dev_test_flag(hdev, HCI_LE_SCAN)) |
---|
431 | 433 | return; |
---|
432 | 434 | |
---|
433 | | - hci_req_add_le_scan_disable(req); |
---|
| 435 | + hci_req_add_le_scan_disable(req, false); |
---|
434 | 436 | |
---|
435 | 437 | BT_DBG("%s stopping background scanning", hdev->name); |
---|
436 | 438 | } else { |
---|
.. | .. |
---|
449 | 451 | * don't miss any advertising (due to duplicates filter). |
---|
450 | 452 | */ |
---|
451 | 453 | if (hci_dev_test_flag(hdev, HCI_LE_SCAN)) |
---|
452 | | - hci_req_add_le_scan_disable(req); |
---|
| 454 | + hci_req_add_le_scan_disable(req, false); |
---|
453 | 455 | |
---|
454 | 456 | hci_req_add_le_passive_scan(req); |
---|
455 | 457 | |
---|
.. | .. |
---|
654 | 656 | hci_req_add(req, HCI_OP_WRITE_EIR, sizeof(cp), &cp); |
---|
655 | 657 | } |
---|
656 | 658 | |
---|
657 | | -void hci_req_add_le_scan_disable(struct hci_request *req) |
---|
| 659 | +void hci_req_add_le_scan_disable(struct hci_request *req, bool rpa_le_conn) |
---|
658 | 660 | { |
---|
659 | 661 | struct hci_dev *hdev = req->hdev; |
---|
| 662 | + |
---|
| 663 | + if (hdev->scanning_paused) { |
---|
| 664 | + bt_dev_dbg(hdev, "Scanning is paused for suspend"); |
---|
| 665 | + return; |
---|
| 666 | + } |
---|
660 | 667 | |
---|
661 | 668 | if (use_ext_scan(hdev)) { |
---|
662 | 669 | struct hci_cp_le_set_ext_scan_enable cp; |
---|
.. | .. |
---|
672 | 679 | cp.enable = LE_SCAN_DISABLE; |
---|
673 | 680 | hci_req_add(req, HCI_OP_LE_SET_SCAN_ENABLE, sizeof(cp), &cp); |
---|
674 | 681 | } |
---|
| 682 | + |
---|
| 683 | + /* Disable address resolution */ |
---|
| 684 | + if (use_ll_privacy(hdev) && |
---|
| 685 | + hci_dev_test_flag(hdev, HCI_ENABLE_LL_PRIVACY) && |
---|
| 686 | + hci_dev_test_flag(hdev, HCI_LL_RPA_RESOLUTION) && !rpa_le_conn) { |
---|
| 687 | + __u8 enable = 0x00; |
---|
| 688 | + |
---|
| 689 | + hci_req_add(req, HCI_OP_LE_SET_ADDR_RESOLV_ENABLE, 1, &enable); |
---|
| 690 | + } |
---|
675 | 691 | } |
---|
676 | 692 | |
---|
677 | | -static void add_to_white_list(struct hci_request *req, |
---|
678 | | - struct hci_conn_params *params) |
---|
| 693 | +static void del_from_white_list(struct hci_request *req, bdaddr_t *bdaddr, |
---|
| 694 | + u8 bdaddr_type) |
---|
| 695 | +{ |
---|
| 696 | + struct hci_cp_le_del_from_white_list cp; |
---|
| 697 | + |
---|
| 698 | + cp.bdaddr_type = bdaddr_type; |
---|
| 699 | + bacpy(&cp.bdaddr, bdaddr); |
---|
| 700 | + |
---|
| 701 | + bt_dev_dbg(req->hdev, "Remove %pMR (0x%x) from whitelist", &cp.bdaddr, |
---|
| 702 | + cp.bdaddr_type); |
---|
| 703 | + hci_req_add(req, HCI_OP_LE_DEL_FROM_WHITE_LIST, sizeof(cp), &cp); |
---|
| 704 | + |
---|
| 705 | + if (use_ll_privacy(req->hdev) && |
---|
| 706 | + hci_dev_test_flag(req->hdev, HCI_ENABLE_LL_PRIVACY)) { |
---|
| 707 | + struct smp_irk *irk; |
---|
| 708 | + |
---|
| 709 | + irk = hci_find_irk_by_addr(req->hdev, bdaddr, bdaddr_type); |
---|
| 710 | + if (irk) { |
---|
| 711 | + struct hci_cp_le_del_from_resolv_list cp; |
---|
| 712 | + |
---|
| 713 | + cp.bdaddr_type = bdaddr_type; |
---|
| 714 | + bacpy(&cp.bdaddr, bdaddr); |
---|
| 715 | + |
---|
| 716 | + hci_req_add(req, HCI_OP_LE_DEL_FROM_RESOLV_LIST, |
---|
| 717 | + sizeof(cp), &cp); |
---|
| 718 | + } |
---|
| 719 | + } |
---|
| 720 | +} |
---|
| 721 | + |
---|
| 722 | +/* Adds connection to white list if needed. On error, returns -1. */ |
---|
| 723 | +static int add_to_white_list(struct hci_request *req, |
---|
| 724 | + struct hci_conn_params *params, u8 *num_entries, |
---|
| 725 | + bool allow_rpa) |
---|
679 | 726 | { |
---|
680 | 727 | struct hci_cp_le_add_to_white_list cp; |
---|
| 728 | + struct hci_dev *hdev = req->hdev; |
---|
681 | 729 | |
---|
| 730 | + /* Already in white list */ |
---|
| 731 | + if (hci_bdaddr_list_lookup(&hdev->le_white_list, ¶ms->addr, |
---|
| 732 | + params->addr_type)) |
---|
| 733 | + return 0; |
---|
| 734 | + |
---|
| 735 | + /* Select filter policy to accept all advertising */ |
---|
| 736 | + if (*num_entries >= hdev->le_white_list_size) |
---|
| 737 | + return -1; |
---|
| 738 | + |
---|
| 739 | + /* White list can not be used with RPAs */ |
---|
| 740 | + if (!allow_rpa && |
---|
| 741 | + !hci_dev_test_flag(hdev, HCI_ENABLE_LL_PRIVACY) && |
---|
| 742 | + hci_find_irk_by_addr(hdev, ¶ms->addr, params->addr_type)) { |
---|
| 743 | + return -1; |
---|
| 744 | + } |
---|
| 745 | + |
---|
| 746 | + /* During suspend, only wakeable devices can be in whitelist */ |
---|
| 747 | + if (hdev->suspended && !hci_conn_test_flag(HCI_CONN_FLAG_REMOTE_WAKEUP, |
---|
| 748 | + params->current_flags)) |
---|
| 749 | + return 0; |
---|
| 750 | + |
---|
| 751 | + *num_entries += 1; |
---|
682 | 752 | cp.bdaddr_type = params->addr_type; |
---|
683 | 753 | bacpy(&cp.bdaddr, ¶ms->addr); |
---|
684 | 754 | |
---|
| 755 | + bt_dev_dbg(hdev, "Add %pMR (0x%x) to whitelist", &cp.bdaddr, |
---|
| 756 | + cp.bdaddr_type); |
---|
685 | 757 | hci_req_add(req, HCI_OP_LE_ADD_TO_WHITE_LIST, sizeof(cp), &cp); |
---|
| 758 | + |
---|
| 759 | + if (use_ll_privacy(hdev) && |
---|
| 760 | + hci_dev_test_flag(hdev, HCI_ENABLE_LL_PRIVACY)) { |
---|
| 761 | + struct smp_irk *irk; |
---|
| 762 | + |
---|
| 763 | + irk = hci_find_irk_by_addr(hdev, ¶ms->addr, |
---|
| 764 | + params->addr_type); |
---|
| 765 | + if (irk) { |
---|
| 766 | + struct hci_cp_le_add_to_resolv_list cp; |
---|
| 767 | + |
---|
| 768 | + cp.bdaddr_type = params->addr_type; |
---|
| 769 | + bacpy(&cp.bdaddr, ¶ms->addr); |
---|
| 770 | + memcpy(cp.peer_irk, irk->val, 16); |
---|
| 771 | + |
---|
| 772 | + if (hci_dev_test_flag(hdev, HCI_PRIVACY)) |
---|
| 773 | + memcpy(cp.local_irk, hdev->irk, 16); |
---|
| 774 | + else |
---|
| 775 | + memset(cp.local_irk, 0, 16); |
---|
| 776 | + |
---|
| 777 | + hci_req_add(req, HCI_OP_LE_ADD_TO_RESOLV_LIST, |
---|
| 778 | + sizeof(cp), &cp); |
---|
| 779 | + } |
---|
| 780 | + } |
---|
| 781 | + |
---|
| 782 | + return 0; |
---|
686 | 783 | } |
---|
687 | 784 | |
---|
688 | 785 | static u8 update_white_list(struct hci_request *req) |
---|
.. | .. |
---|
690 | 787 | struct hci_dev *hdev = req->hdev; |
---|
691 | 788 | struct hci_conn_params *params; |
---|
692 | 789 | struct bdaddr_list *b; |
---|
693 | | - uint8_t white_list_entries = 0; |
---|
| 790 | + u8 num_entries = 0; |
---|
| 791 | + bool pend_conn, pend_report; |
---|
| 792 | + /* We allow whitelisting even with RPAs in suspend. In the worst case, |
---|
| 793 | + * we won't be able to wake from devices that use the privacy1.2 |
---|
| 794 | + * features. Additionally, once we support privacy1.2 and IRK |
---|
| 795 | + * offloading, we can update this to also check for those conditions. |
---|
| 796 | + */ |
---|
| 797 | + bool allow_rpa = hdev->suspended; |
---|
| 798 | + |
---|
| 799 | + if (use_ll_privacy(hdev) && |
---|
| 800 | + hci_dev_test_flag(hdev, HCI_ENABLE_LL_PRIVACY)) |
---|
| 801 | + allow_rpa = true; |
---|
694 | 802 | |
---|
695 | 803 | /* Go through the current white list programmed into the |
---|
696 | 804 | * controller one by one and check if that address is still |
---|
.. | .. |
---|
699 | 807 | * command to remove it from the controller. |
---|
700 | 808 | */ |
---|
701 | 809 | list_for_each_entry(b, &hdev->le_white_list, list) { |
---|
702 | | - /* If the device is neither in pend_le_conns nor |
---|
703 | | - * pend_le_reports then remove it from the whitelist. |
---|
| 810 | + pend_conn = hci_pend_le_action_lookup(&hdev->pend_le_conns, |
---|
| 811 | + &b->bdaddr, |
---|
| 812 | + b->bdaddr_type); |
---|
| 813 | + pend_report = hci_pend_le_action_lookup(&hdev->pend_le_reports, |
---|
| 814 | + &b->bdaddr, |
---|
| 815 | + b->bdaddr_type); |
---|
| 816 | + |
---|
| 817 | + /* If the device is not likely to connect or report, |
---|
| 818 | + * remove it from the whitelist. |
---|
704 | 819 | */ |
---|
705 | | - if (!hci_pend_le_action_lookup(&hdev->pend_le_conns, |
---|
706 | | - &b->bdaddr, b->bdaddr_type) && |
---|
707 | | - !hci_pend_le_action_lookup(&hdev->pend_le_reports, |
---|
708 | | - &b->bdaddr, b->bdaddr_type)) { |
---|
709 | | - struct hci_cp_le_del_from_white_list cp; |
---|
710 | | - |
---|
711 | | - cp.bdaddr_type = b->bdaddr_type; |
---|
712 | | - bacpy(&cp.bdaddr, &b->bdaddr); |
---|
713 | | - |
---|
714 | | - hci_req_add(req, HCI_OP_LE_DEL_FROM_WHITE_LIST, |
---|
715 | | - sizeof(cp), &cp); |
---|
| 820 | + if (!pend_conn && !pend_report) { |
---|
| 821 | + del_from_white_list(req, &b->bdaddr, b->bdaddr_type); |
---|
716 | 822 | continue; |
---|
717 | 823 | } |
---|
718 | 824 | |
---|
719 | | - if (hci_find_irk_by_addr(hdev, &b->bdaddr, b->bdaddr_type)) { |
---|
720 | | - /* White list can not be used with RPAs */ |
---|
| 825 | + /* White list can not be used with RPAs */ |
---|
| 826 | + if (!allow_rpa && |
---|
| 827 | + !hci_dev_test_flag(hdev, HCI_ENABLE_LL_PRIVACY) && |
---|
| 828 | + hci_find_irk_by_addr(hdev, &b->bdaddr, b->bdaddr_type)) { |
---|
721 | 829 | return 0x00; |
---|
722 | 830 | } |
---|
723 | 831 | |
---|
724 | | - white_list_entries++; |
---|
| 832 | + num_entries++; |
---|
725 | 833 | } |
---|
726 | 834 | |
---|
727 | 835 | /* Since all no longer valid white list entries have been |
---|
.. | .. |
---|
735 | 843 | * white list. |
---|
736 | 844 | */ |
---|
737 | 845 | list_for_each_entry(params, &hdev->pend_le_conns, action) { |
---|
738 | | - if (hci_bdaddr_list_lookup(&hdev->le_white_list, |
---|
739 | | - ¶ms->addr, params->addr_type)) |
---|
740 | | - continue; |
---|
741 | | - |
---|
742 | | - if (white_list_entries >= hdev->le_white_list_size) { |
---|
743 | | - /* Select filter policy to accept all advertising */ |
---|
| 846 | + if (add_to_white_list(req, params, &num_entries, allow_rpa)) |
---|
744 | 847 | return 0x00; |
---|
745 | | - } |
---|
746 | | - |
---|
747 | | - if (hci_find_irk_by_addr(hdev, ¶ms->addr, |
---|
748 | | - params->addr_type)) { |
---|
749 | | - /* White list can not be used with RPAs */ |
---|
750 | | - return 0x00; |
---|
751 | | - } |
---|
752 | | - |
---|
753 | | - white_list_entries++; |
---|
754 | | - add_to_white_list(req, params); |
---|
755 | 848 | } |
---|
756 | 849 | |
---|
757 | 850 | /* After adding all new pending connections, walk through |
---|
758 | 851 | * the list of pending reports and also add these to the |
---|
759 | | - * white list if there is still space. |
---|
| 852 | + * white list if there is still space. Abort if space runs out. |
---|
760 | 853 | */ |
---|
761 | 854 | list_for_each_entry(params, &hdev->pend_le_reports, action) { |
---|
762 | | - if (hci_bdaddr_list_lookup(&hdev->le_white_list, |
---|
763 | | - ¶ms->addr, params->addr_type)) |
---|
764 | | - continue; |
---|
765 | | - |
---|
766 | | - if (white_list_entries >= hdev->le_white_list_size) { |
---|
767 | | - /* Select filter policy to accept all advertising */ |
---|
| 855 | + if (add_to_white_list(req, params, &num_entries, allow_rpa)) |
---|
768 | 856 | return 0x00; |
---|
769 | | - } |
---|
770 | | - |
---|
771 | | - if (hci_find_irk_by_addr(hdev, ¶ms->addr, |
---|
772 | | - params->addr_type)) { |
---|
773 | | - /* White list can not be used with RPAs */ |
---|
774 | | - return 0x00; |
---|
775 | | - } |
---|
776 | | - |
---|
777 | | - white_list_entries++; |
---|
778 | | - add_to_white_list(req, params); |
---|
779 | 857 | } |
---|
| 858 | + |
---|
| 859 | + /* Once the controller offloading of advertisement monitor is in place, |
---|
| 860 | + * the if condition should include the support of MSFT extension |
---|
| 861 | + * support. If suspend is ongoing, whitelist should be the default to |
---|
| 862 | + * prevent waking by random advertisements. |
---|
| 863 | + */ |
---|
| 864 | + if (!idr_is_empty(&hdev->adv_monitors_idr) && !hdev->suspended) |
---|
| 865 | + return 0x00; |
---|
780 | 866 | |
---|
781 | 867 | /* Select filter policy to use white list */ |
---|
782 | 868 | return 0x01; |
---|
.. | .. |
---|
788 | 874 | } |
---|
789 | 875 | |
---|
790 | 876 | static void hci_req_start_scan(struct hci_request *req, u8 type, u16 interval, |
---|
791 | | - u16 window, u8 own_addr_type, u8 filter_policy) |
---|
| 877 | + u16 window, u8 own_addr_type, u8 filter_policy, |
---|
| 878 | + bool addr_resolv) |
---|
792 | 879 | { |
---|
793 | 880 | struct hci_dev *hdev = req->hdev; |
---|
| 881 | + |
---|
| 882 | + if (hdev->scanning_paused) { |
---|
| 883 | + bt_dev_dbg(hdev, "Scanning is paused for suspend"); |
---|
| 884 | + return; |
---|
| 885 | + } |
---|
| 886 | + |
---|
| 887 | + if (use_ll_privacy(hdev) && |
---|
| 888 | + hci_dev_test_flag(hdev, HCI_ENABLE_LL_PRIVACY) && |
---|
| 889 | + addr_resolv) { |
---|
| 890 | + u8 enable = 0x01; |
---|
| 891 | + |
---|
| 892 | + hci_req_add(req, HCI_OP_LE_SET_ADDR_RESOLV_ENABLE, 1, &enable); |
---|
| 893 | + } |
---|
794 | 894 | |
---|
795 | 895 | /* Use ext scanning if set ext scan param and ext scan enable is |
---|
796 | 896 | * supported |
---|
.. | .. |
---|
865 | 965 | } |
---|
866 | 966 | } |
---|
867 | 967 | |
---|
| 968 | +/* Returns true if an le connection is in the scanning state */ |
---|
| 969 | +static inline bool hci_is_le_conn_scanning(struct hci_dev *hdev) |
---|
| 970 | +{ |
---|
| 971 | + struct hci_conn_hash *h = &hdev->conn_hash; |
---|
| 972 | + struct hci_conn *c; |
---|
| 973 | + |
---|
| 974 | + rcu_read_lock(); |
---|
| 975 | + |
---|
| 976 | + list_for_each_entry_rcu(c, &h->list, list) { |
---|
| 977 | + if (c->type == LE_LINK && c->state == BT_CONNECT && |
---|
| 978 | + test_bit(HCI_CONN_SCANNING, &c->flags)) { |
---|
| 979 | + rcu_read_unlock(); |
---|
| 980 | + return true; |
---|
| 981 | + } |
---|
| 982 | + } |
---|
| 983 | + |
---|
| 984 | + rcu_read_unlock(); |
---|
| 985 | + |
---|
| 986 | + return false; |
---|
| 987 | +} |
---|
| 988 | + |
---|
| 989 | +/* Ensure to call hci_req_add_le_scan_disable() first to disable the |
---|
| 990 | + * controller based address resolution to be able to reconfigure |
---|
| 991 | + * resolving list. |
---|
| 992 | + */ |
---|
868 | 993 | void hci_req_add_le_passive_scan(struct hci_request *req) |
---|
869 | 994 | { |
---|
870 | 995 | struct hci_dev *hdev = req->hdev; |
---|
871 | 996 | u8 own_addr_type; |
---|
872 | 997 | u8 filter_policy; |
---|
| 998 | + u16 window, interval; |
---|
| 999 | + /* Background scanning should run with address resolution */ |
---|
| 1000 | + bool addr_resolv = true; |
---|
| 1001 | + |
---|
| 1002 | + if (hdev->scanning_paused) { |
---|
| 1003 | + bt_dev_dbg(hdev, "Scanning is paused for suspend"); |
---|
| 1004 | + return; |
---|
| 1005 | + } |
---|
873 | 1006 | |
---|
874 | 1007 | /* Set require_privacy to false since no SCAN_REQ are send |
---|
875 | 1008 | * during passive scanning. Not using an non-resolvable address |
---|
.. | .. |
---|
900 | 1033 | (hdev->le_features[0] & HCI_LE_EXT_SCAN_POLICY)) |
---|
901 | 1034 | filter_policy |= 0x02; |
---|
902 | 1035 | |
---|
903 | | - hci_req_start_scan(req, LE_SCAN_PASSIVE, hdev->le_scan_interval, |
---|
904 | | - hdev->le_scan_window, own_addr_type, filter_policy); |
---|
| 1036 | + if (hdev->suspended) { |
---|
| 1037 | + window = hdev->le_scan_window_suspend; |
---|
| 1038 | + interval = hdev->le_scan_int_suspend; |
---|
| 1039 | + } else if (hci_is_le_conn_scanning(hdev)) { |
---|
| 1040 | + window = hdev->le_scan_window_connect; |
---|
| 1041 | + interval = hdev->le_scan_int_connect; |
---|
| 1042 | + } else if (hci_is_adv_monitoring(hdev)) { |
---|
| 1043 | + window = hdev->le_scan_window_adv_monitor; |
---|
| 1044 | + interval = hdev->le_scan_int_adv_monitor; |
---|
| 1045 | + } else { |
---|
| 1046 | + window = hdev->le_scan_window; |
---|
| 1047 | + interval = hdev->le_scan_interval; |
---|
| 1048 | + } |
---|
| 1049 | + |
---|
| 1050 | + bt_dev_dbg(hdev, "LE passive scan with whitelist = %d", filter_policy); |
---|
| 1051 | + hci_req_start_scan(req, LE_SCAN_PASSIVE, interval, window, |
---|
| 1052 | + own_addr_type, filter_policy, addr_resolv); |
---|
905 | 1053 | } |
---|
906 | 1054 | |
---|
907 | 1055 | static u8 get_adv_instance_scan_rsp_len(struct hci_dev *hdev, u8 instance) |
---|
908 | 1056 | { |
---|
909 | 1057 | struct adv_info *adv_instance; |
---|
910 | 1058 | |
---|
911 | | - /* Ignore instance 0 */ |
---|
| 1059 | + /* Instance 0x00 always set local name */ |
---|
912 | 1060 | if (instance == 0x00) |
---|
913 | | - return 0; |
---|
| 1061 | + return 1; |
---|
914 | 1062 | |
---|
915 | 1063 | adv_instance = hci_find_adv_instance(hdev, instance); |
---|
916 | 1064 | if (!adv_instance) |
---|
917 | 1065 | return 0; |
---|
918 | 1066 | |
---|
919 | | - /* TODO: Take into account the "appearance" and "local-name" flags here. |
---|
920 | | - * These are currently being ignored as they are not supported. |
---|
921 | | - */ |
---|
| 1067 | + if (adv_instance->flags & MGMT_ADV_FLAG_APPEARANCE || |
---|
| 1068 | + adv_instance->flags & MGMT_ADV_FLAG_LOCAL_NAME) |
---|
| 1069 | + return 1; |
---|
| 1070 | + |
---|
922 | 1071 | return adv_instance->scan_rsp_len; |
---|
| 1072 | +} |
---|
| 1073 | + |
---|
| 1074 | +static void hci_req_clear_event_filter(struct hci_request *req) |
---|
| 1075 | +{ |
---|
| 1076 | + struct hci_cp_set_event_filter f; |
---|
| 1077 | + |
---|
| 1078 | + memset(&f, 0, sizeof(f)); |
---|
| 1079 | + f.flt_type = HCI_FLT_CLEAR_ALL; |
---|
| 1080 | + hci_req_add(req, HCI_OP_SET_EVENT_FLT, 1, &f); |
---|
| 1081 | + |
---|
| 1082 | + /* Update page scan state (since we may have modified it when setting |
---|
| 1083 | + * the event filter). |
---|
| 1084 | + */ |
---|
| 1085 | + __hci_req_update_scan(req); |
---|
| 1086 | +} |
---|
| 1087 | + |
---|
| 1088 | +static void hci_req_set_event_filter(struct hci_request *req) |
---|
| 1089 | +{ |
---|
| 1090 | + struct bdaddr_list_with_flags *b; |
---|
| 1091 | + struct hci_cp_set_event_filter f; |
---|
| 1092 | + struct hci_dev *hdev = req->hdev; |
---|
| 1093 | + u8 scan = SCAN_DISABLED; |
---|
| 1094 | + |
---|
| 1095 | + /* Always clear event filter when starting */ |
---|
| 1096 | + hci_req_clear_event_filter(req); |
---|
| 1097 | + |
---|
| 1098 | + list_for_each_entry(b, &hdev->whitelist, list) { |
---|
| 1099 | + if (!hci_conn_test_flag(HCI_CONN_FLAG_REMOTE_WAKEUP, |
---|
| 1100 | + b->current_flags)) |
---|
| 1101 | + continue; |
---|
| 1102 | + |
---|
| 1103 | + memset(&f, 0, sizeof(f)); |
---|
| 1104 | + bacpy(&f.addr_conn_flt.bdaddr, &b->bdaddr); |
---|
| 1105 | + f.flt_type = HCI_FLT_CONN_SETUP; |
---|
| 1106 | + f.cond_type = HCI_CONN_SETUP_ALLOW_BDADDR; |
---|
| 1107 | + f.addr_conn_flt.auto_accept = HCI_CONN_SETUP_AUTO_ON; |
---|
| 1108 | + |
---|
| 1109 | + bt_dev_dbg(hdev, "Adding event filters for %pMR", &b->bdaddr); |
---|
| 1110 | + hci_req_add(req, HCI_OP_SET_EVENT_FLT, sizeof(f), &f); |
---|
| 1111 | + scan = SCAN_PAGE; |
---|
| 1112 | + } |
---|
| 1113 | + |
---|
| 1114 | + hci_req_add(req, HCI_OP_WRITE_SCAN_ENABLE, 1, &scan); |
---|
| 1115 | +} |
---|
| 1116 | + |
---|
| 1117 | +static void hci_req_config_le_suspend_scan(struct hci_request *req) |
---|
| 1118 | +{ |
---|
| 1119 | + /* Before changing params disable scan if enabled */ |
---|
| 1120 | + if (hci_dev_test_flag(req->hdev, HCI_LE_SCAN)) |
---|
| 1121 | + hci_req_add_le_scan_disable(req, false); |
---|
| 1122 | + |
---|
| 1123 | + /* Configure params and enable scanning */ |
---|
| 1124 | + hci_req_add_le_passive_scan(req); |
---|
| 1125 | + |
---|
| 1126 | + /* Block suspend notifier on response */ |
---|
| 1127 | + set_bit(SUSPEND_SCAN_ENABLE, req->hdev->suspend_tasks); |
---|
| 1128 | +} |
---|
| 1129 | + |
---|
| 1130 | +static void cancel_adv_timeout(struct hci_dev *hdev) |
---|
| 1131 | +{ |
---|
| 1132 | + if (hdev->adv_instance_timeout) { |
---|
| 1133 | + hdev->adv_instance_timeout = 0; |
---|
| 1134 | + cancel_delayed_work(&hdev->adv_instance_expire); |
---|
| 1135 | + } |
---|
| 1136 | +} |
---|
| 1137 | + |
---|
| 1138 | +/* This function requires the caller holds hdev->lock */ |
---|
| 1139 | +static void hci_suspend_adv_instances(struct hci_request *req) |
---|
| 1140 | +{ |
---|
| 1141 | + bt_dev_dbg(req->hdev, "Suspending advertising instances"); |
---|
| 1142 | + |
---|
| 1143 | + /* Call to disable any advertisements active on the controller. |
---|
| 1144 | + * This will succeed even if no advertisements are configured. |
---|
| 1145 | + */ |
---|
| 1146 | + __hci_req_disable_advertising(req); |
---|
| 1147 | + |
---|
| 1148 | + /* If we are using software rotation, pause the loop */ |
---|
| 1149 | + if (!ext_adv_capable(req->hdev)) |
---|
| 1150 | + cancel_adv_timeout(req->hdev); |
---|
| 1151 | +} |
---|
| 1152 | + |
---|
| 1153 | +/* This function requires the caller holds hdev->lock */ |
---|
| 1154 | +static void hci_resume_adv_instances(struct hci_request *req) |
---|
| 1155 | +{ |
---|
| 1156 | + struct adv_info *adv; |
---|
| 1157 | + |
---|
| 1158 | + bt_dev_dbg(req->hdev, "Resuming advertising instances"); |
---|
| 1159 | + |
---|
| 1160 | + if (ext_adv_capable(req->hdev)) { |
---|
| 1161 | + /* Call for each tracked instance to be re-enabled */ |
---|
| 1162 | + list_for_each_entry(adv, &req->hdev->adv_instances, list) { |
---|
| 1163 | + __hci_req_enable_ext_advertising(req, |
---|
| 1164 | + adv->instance); |
---|
| 1165 | + } |
---|
| 1166 | + |
---|
| 1167 | + } else { |
---|
| 1168 | + /* Schedule for most recent instance to be restarted and begin |
---|
| 1169 | + * the software rotation loop |
---|
| 1170 | + */ |
---|
| 1171 | + __hci_req_schedule_adv_instance(req, |
---|
| 1172 | + req->hdev->cur_adv_instance, |
---|
| 1173 | + true); |
---|
| 1174 | + } |
---|
| 1175 | +} |
---|
| 1176 | + |
---|
| 1177 | +static void suspend_req_complete(struct hci_dev *hdev, u8 status, u16 opcode) |
---|
| 1178 | +{ |
---|
| 1179 | + bt_dev_dbg(hdev, "Request complete opcode=0x%x, status=0x%x", opcode, |
---|
| 1180 | + status); |
---|
| 1181 | + if (test_and_clear_bit(SUSPEND_SCAN_ENABLE, hdev->suspend_tasks) || |
---|
| 1182 | + test_and_clear_bit(SUSPEND_SCAN_DISABLE, hdev->suspend_tasks)) { |
---|
| 1183 | + wake_up(&hdev->suspend_wait_q); |
---|
| 1184 | + } |
---|
| 1185 | +} |
---|
| 1186 | + |
---|
| 1187 | +/* Call with hci_dev_lock */ |
---|
| 1188 | +void hci_req_prepare_suspend(struct hci_dev *hdev, enum suspended_state next) |
---|
| 1189 | +{ |
---|
| 1190 | + int old_state; |
---|
| 1191 | + struct hci_conn *conn; |
---|
| 1192 | + struct hci_request req; |
---|
| 1193 | + u8 page_scan; |
---|
| 1194 | + int disconnect_counter; |
---|
| 1195 | + |
---|
| 1196 | + if (next == hdev->suspend_state) { |
---|
| 1197 | + bt_dev_dbg(hdev, "Same state before and after: %d", next); |
---|
| 1198 | + goto done; |
---|
| 1199 | + } |
---|
| 1200 | + |
---|
| 1201 | + hdev->suspend_state = next; |
---|
| 1202 | + hci_req_init(&req, hdev); |
---|
| 1203 | + |
---|
| 1204 | + if (next == BT_SUSPEND_DISCONNECT) { |
---|
| 1205 | + /* Mark device as suspended */ |
---|
| 1206 | + hdev->suspended = true; |
---|
| 1207 | + |
---|
| 1208 | + /* Pause discovery if not already stopped */ |
---|
| 1209 | + old_state = hdev->discovery.state; |
---|
| 1210 | + if (old_state != DISCOVERY_STOPPED) { |
---|
| 1211 | + set_bit(SUSPEND_PAUSE_DISCOVERY, hdev->suspend_tasks); |
---|
| 1212 | + hci_discovery_set_state(hdev, DISCOVERY_STOPPING); |
---|
| 1213 | + queue_work(hdev->req_workqueue, &hdev->discov_update); |
---|
| 1214 | + } |
---|
| 1215 | + |
---|
| 1216 | + hdev->discovery_paused = true; |
---|
| 1217 | + hdev->discovery_old_state = old_state; |
---|
| 1218 | + |
---|
| 1219 | + /* Stop directed advertising */ |
---|
| 1220 | + old_state = hci_dev_test_flag(hdev, HCI_ADVERTISING); |
---|
| 1221 | + if (old_state) { |
---|
| 1222 | + set_bit(SUSPEND_PAUSE_ADVERTISING, hdev->suspend_tasks); |
---|
| 1223 | + cancel_delayed_work(&hdev->discov_off); |
---|
| 1224 | + queue_delayed_work(hdev->req_workqueue, |
---|
| 1225 | + &hdev->discov_off, 0); |
---|
| 1226 | + } |
---|
| 1227 | + |
---|
| 1228 | + /* Pause other advertisements */ |
---|
| 1229 | + if (hdev->adv_instance_cnt) |
---|
| 1230 | + hci_suspend_adv_instances(&req); |
---|
| 1231 | + |
---|
| 1232 | + hdev->advertising_paused = true; |
---|
| 1233 | + hdev->advertising_old_state = old_state; |
---|
| 1234 | + /* Disable page scan */ |
---|
| 1235 | + page_scan = SCAN_DISABLED; |
---|
| 1236 | + hci_req_add(&req, HCI_OP_WRITE_SCAN_ENABLE, 1, &page_scan); |
---|
| 1237 | + |
---|
| 1238 | + /* Disable LE passive scan if enabled */ |
---|
| 1239 | + if (hci_dev_test_flag(hdev, HCI_LE_SCAN)) |
---|
| 1240 | + hci_req_add_le_scan_disable(&req, false); |
---|
| 1241 | + |
---|
| 1242 | + /* Mark task needing completion */ |
---|
| 1243 | + set_bit(SUSPEND_SCAN_DISABLE, hdev->suspend_tasks); |
---|
| 1244 | + |
---|
| 1245 | + /* Prevent disconnects from causing scanning to be re-enabled */ |
---|
| 1246 | + hdev->scanning_paused = true; |
---|
| 1247 | + |
---|
| 1248 | + /* Run commands before disconnecting */ |
---|
| 1249 | + hci_req_run(&req, suspend_req_complete); |
---|
| 1250 | + |
---|
| 1251 | + disconnect_counter = 0; |
---|
| 1252 | + /* Soft disconnect everything (power off) */ |
---|
| 1253 | + list_for_each_entry(conn, &hdev->conn_hash.list, list) { |
---|
| 1254 | + hci_disconnect(conn, HCI_ERROR_REMOTE_POWER_OFF); |
---|
| 1255 | + disconnect_counter++; |
---|
| 1256 | + } |
---|
| 1257 | + |
---|
| 1258 | + if (disconnect_counter > 0) { |
---|
| 1259 | + bt_dev_dbg(hdev, |
---|
| 1260 | + "Had %d disconnects. Will wait on them", |
---|
| 1261 | + disconnect_counter); |
---|
| 1262 | + set_bit(SUSPEND_DISCONNECTING, hdev->suspend_tasks); |
---|
| 1263 | + } |
---|
| 1264 | + } else if (next == BT_SUSPEND_CONFIGURE_WAKE) { |
---|
| 1265 | + /* Unpause to take care of updating scanning params */ |
---|
| 1266 | + hdev->scanning_paused = false; |
---|
| 1267 | + /* Enable event filter for paired devices */ |
---|
| 1268 | + hci_req_set_event_filter(&req); |
---|
| 1269 | + /* Enable passive scan at lower duty cycle */ |
---|
| 1270 | + hci_req_config_le_suspend_scan(&req); |
---|
| 1271 | + /* Pause scan changes again. */ |
---|
| 1272 | + hdev->scanning_paused = true; |
---|
| 1273 | + hci_req_run(&req, suspend_req_complete); |
---|
| 1274 | + } else { |
---|
| 1275 | + hdev->suspended = false; |
---|
| 1276 | + hdev->scanning_paused = false; |
---|
| 1277 | + |
---|
| 1278 | + hci_req_clear_event_filter(&req); |
---|
| 1279 | + /* Reset passive/background scanning to normal */ |
---|
| 1280 | + hci_req_config_le_suspend_scan(&req); |
---|
| 1281 | + |
---|
| 1282 | + /* Unpause directed advertising */ |
---|
| 1283 | + hdev->advertising_paused = false; |
---|
| 1284 | + if (hdev->advertising_old_state) { |
---|
| 1285 | + set_bit(SUSPEND_UNPAUSE_ADVERTISING, |
---|
| 1286 | + hdev->suspend_tasks); |
---|
| 1287 | + hci_dev_set_flag(hdev, HCI_ADVERTISING); |
---|
| 1288 | + queue_work(hdev->req_workqueue, |
---|
| 1289 | + &hdev->discoverable_update); |
---|
| 1290 | + hdev->advertising_old_state = 0; |
---|
| 1291 | + } |
---|
| 1292 | + |
---|
| 1293 | + /* Resume other advertisements */ |
---|
| 1294 | + if (hdev->adv_instance_cnt) |
---|
| 1295 | + hci_resume_adv_instances(&req); |
---|
| 1296 | + |
---|
| 1297 | + /* Unpause discovery */ |
---|
| 1298 | + hdev->discovery_paused = false; |
---|
| 1299 | + if (hdev->discovery_old_state != DISCOVERY_STOPPED && |
---|
| 1300 | + hdev->discovery_old_state != DISCOVERY_STOPPING) { |
---|
| 1301 | + set_bit(SUSPEND_UNPAUSE_DISCOVERY, hdev->suspend_tasks); |
---|
| 1302 | + hci_discovery_set_state(hdev, DISCOVERY_STARTING); |
---|
| 1303 | + queue_work(hdev->req_workqueue, &hdev->discov_update); |
---|
| 1304 | + } |
---|
| 1305 | + |
---|
| 1306 | + hci_req_run(&req, suspend_req_complete); |
---|
| 1307 | + } |
---|
| 1308 | + |
---|
| 1309 | + hdev->suspend_state = next; |
---|
| 1310 | + |
---|
| 1311 | +done: |
---|
| 1312 | + clear_bit(SUSPEND_PREPARE_NOTIFIER, hdev->suspend_tasks); |
---|
| 1313 | + wake_up(&hdev->suspend_wait_q); |
---|
923 | 1314 | } |
---|
924 | 1315 | |
---|
925 | 1316 | static u8 get_cur_adv_instance_scan_rsp_len(struct hci_dev *hdev) |
---|
.. | .. |
---|
927 | 1318 | u8 instance = hdev->cur_adv_instance; |
---|
928 | 1319 | struct adv_info *adv_instance; |
---|
929 | 1320 | |
---|
930 | | - /* Ignore instance 0 */ |
---|
| 1321 | + /* Instance 0x00 always set local name */ |
---|
931 | 1322 | if (instance == 0x00) |
---|
932 | | - return 0; |
---|
| 1323 | + return 1; |
---|
933 | 1324 | |
---|
934 | 1325 | adv_instance = hci_find_adv_instance(hdev, instance); |
---|
935 | 1326 | if (!adv_instance) |
---|
.. | .. |
---|
944 | 1335 | void __hci_req_disable_advertising(struct hci_request *req) |
---|
945 | 1336 | { |
---|
946 | 1337 | if (ext_adv_capable(req->hdev)) { |
---|
947 | | - struct hci_cp_le_set_ext_adv_enable cp; |
---|
| 1338 | + __hci_req_disable_ext_adv_instance(req, 0x00); |
---|
948 | 1339 | |
---|
949 | | - cp.enable = 0x00; |
---|
950 | | - /* Disable all sets since we only support one set at the moment */ |
---|
951 | | - cp.num_of_sets = 0x00; |
---|
952 | | - |
---|
953 | | - hci_req_add(req, HCI_OP_LE_SET_EXT_ADV_ENABLE, sizeof(cp), &cp); |
---|
954 | 1340 | } else { |
---|
955 | 1341 | u8 enable = 0x00; |
---|
956 | 1342 | |
---|
.. | .. |
---|
1058 | 1444 | struct hci_cp_le_set_adv_param cp; |
---|
1059 | 1445 | u8 own_addr_type, enable = 0x01; |
---|
1060 | 1446 | bool connectable; |
---|
| 1447 | + u16 adv_min_interval, adv_max_interval; |
---|
1061 | 1448 | u32 flags; |
---|
1062 | 1449 | |
---|
1063 | 1450 | flags = get_adv_instance_flags(hdev, hdev->cur_adv_instance); |
---|
.. | .. |
---|
1091 | 1478 | return; |
---|
1092 | 1479 | |
---|
1093 | 1480 | memset(&cp, 0, sizeof(cp)); |
---|
1094 | | - cp.min_interval = cpu_to_le16(hdev->le_adv_min_interval); |
---|
1095 | | - cp.max_interval = cpu_to_le16(hdev->le_adv_max_interval); |
---|
1096 | 1481 | |
---|
1097 | | - if (connectable) |
---|
| 1482 | + if (connectable) { |
---|
1098 | 1483 | cp.type = LE_ADV_IND; |
---|
1099 | | - else if (get_cur_adv_instance_scan_rsp_len(hdev)) |
---|
1100 | | - cp.type = LE_ADV_SCAN_IND; |
---|
1101 | | - else |
---|
1102 | | - cp.type = LE_ADV_NONCONN_IND; |
---|
1103 | 1484 | |
---|
| 1485 | + adv_min_interval = hdev->le_adv_min_interval; |
---|
| 1486 | + adv_max_interval = hdev->le_adv_max_interval; |
---|
| 1487 | + } else { |
---|
| 1488 | + if (get_cur_adv_instance_scan_rsp_len(hdev)) |
---|
| 1489 | + cp.type = LE_ADV_SCAN_IND; |
---|
| 1490 | + else |
---|
| 1491 | + cp.type = LE_ADV_NONCONN_IND; |
---|
| 1492 | + |
---|
| 1493 | + if (!hci_dev_test_flag(hdev, HCI_DISCOVERABLE) || |
---|
| 1494 | + hci_dev_test_flag(hdev, HCI_LIMITED_DISCOVERABLE)) { |
---|
| 1495 | + adv_min_interval = DISCOV_LE_FAST_ADV_INT_MIN; |
---|
| 1496 | + adv_max_interval = DISCOV_LE_FAST_ADV_INT_MAX; |
---|
| 1497 | + } else { |
---|
| 1498 | + adv_min_interval = hdev->le_adv_min_interval; |
---|
| 1499 | + adv_max_interval = hdev->le_adv_max_interval; |
---|
| 1500 | + } |
---|
| 1501 | + } |
---|
| 1502 | + |
---|
| 1503 | + cp.min_interval = cpu_to_le16(adv_min_interval); |
---|
| 1504 | + cp.max_interval = cpu_to_le16(adv_max_interval); |
---|
1104 | 1505 | cp.own_address_type = own_addr_type; |
---|
1105 | 1506 | cp.channel_map = hdev->le_adv_channel_map; |
---|
1106 | 1507 | |
---|
.. | .. |
---|
1216 | 1617 | memcpy(hdev->scan_rsp_data, cp.data, sizeof(cp.data)); |
---|
1217 | 1618 | hdev->scan_rsp_data_len = len; |
---|
1218 | 1619 | |
---|
1219 | | - cp.handle = 0; |
---|
| 1620 | + cp.handle = instance; |
---|
1220 | 1621 | cp.length = len; |
---|
1221 | 1622 | cp.operation = LE_SET_ADV_DATA_OP_COMPLETE; |
---|
1222 | 1623 | cp.frag_pref = LE_SET_ADV_DATA_NO_FRAG; |
---|
.. | .. |
---|
1360 | 1761 | hdev->adv_data_len = len; |
---|
1361 | 1762 | |
---|
1362 | 1763 | cp.length = len; |
---|
1363 | | - cp.handle = 0; |
---|
| 1764 | + cp.handle = instance; |
---|
1364 | 1765 | cp.operation = LE_SET_ADV_DATA_OP_COMPLETE; |
---|
1365 | 1766 | cp.frag_pref = LE_SET_ADV_DATA_NO_FRAG; |
---|
1366 | 1767 | |
---|
.. | .. |
---|
1394 | 1795 | __hci_req_update_adv_data(&req, instance); |
---|
1395 | 1796 | |
---|
1396 | 1797 | return hci_req_run(&req, NULL); |
---|
| 1798 | +} |
---|
| 1799 | + |
---|
| 1800 | +static void enable_addr_resolution_complete(struct hci_dev *hdev, u8 status, |
---|
| 1801 | + u16 opcode) |
---|
| 1802 | +{ |
---|
| 1803 | + BT_DBG("%s status %u", hdev->name, status); |
---|
| 1804 | +} |
---|
| 1805 | + |
---|
| 1806 | +void hci_req_disable_address_resolution(struct hci_dev *hdev) |
---|
| 1807 | +{ |
---|
| 1808 | + struct hci_request req; |
---|
| 1809 | + __u8 enable = 0x00; |
---|
| 1810 | + |
---|
| 1811 | + if (!use_ll_privacy(hdev) && |
---|
| 1812 | + !hci_dev_test_flag(hdev, HCI_LL_RPA_RESOLUTION)) |
---|
| 1813 | + return; |
---|
| 1814 | + |
---|
| 1815 | + hci_req_init(&req, hdev); |
---|
| 1816 | + |
---|
| 1817 | + hci_req_add(&req, HCI_OP_LE_SET_ADDR_RESOLV_ENABLE, 1, &enable); |
---|
| 1818 | + |
---|
| 1819 | + hci_req_run(&req, enable_addr_resolution_complete); |
---|
1397 | 1820 | } |
---|
1398 | 1821 | |
---|
1399 | 1822 | static void adv_enable_complete(struct hci_dev *hdev, u8 status, u16 opcode) |
---|
.. | .. |
---|
1472 | 1895 | if (use_rpa) { |
---|
1473 | 1896 | int to; |
---|
1474 | 1897 | |
---|
1475 | | - *own_addr_type = ADDR_LE_DEV_RANDOM; |
---|
| 1898 | + /* If Controller supports LL Privacy use own address type is |
---|
| 1899 | + * 0x03 |
---|
| 1900 | + */ |
---|
| 1901 | + if (use_ll_privacy(hdev)) |
---|
| 1902 | + *own_addr_type = ADDR_LE_DEV_RANDOM_RESOLVED; |
---|
| 1903 | + else |
---|
| 1904 | + *own_addr_type = ADDR_LE_DEV_RANDOM; |
---|
1476 | 1905 | |
---|
1477 | 1906 | if (adv_instance) { |
---|
1478 | 1907 | if (!adv_instance->rpa_expired && |
---|
.. | .. |
---|
1488 | 1917 | |
---|
1489 | 1918 | err = smp_generate_rpa(hdev, hdev->irk, &hdev->rpa); |
---|
1490 | 1919 | if (err < 0) { |
---|
1491 | | - BT_ERR("%s failed to generate new RPA", hdev->name); |
---|
| 1920 | + bt_dev_err(hdev, "failed to generate new RPA"); |
---|
1492 | 1921 | return err; |
---|
1493 | 1922 | } |
---|
1494 | 1923 | |
---|
.. | .. |
---|
1555 | 1984 | int err; |
---|
1556 | 1985 | struct adv_info *adv_instance; |
---|
1557 | 1986 | bool secondary_adv; |
---|
1558 | | - /* In ext adv set param interval is 3 octets */ |
---|
1559 | | - const u8 adv_interval[3] = { 0x00, 0x08, 0x00 }; |
---|
1560 | 1987 | |
---|
1561 | 1988 | if (instance > 0) { |
---|
1562 | 1989 | adv_instance = hci_find_adv_instance(hdev, instance); |
---|
.. | .. |
---|
1574 | 2001 | connectable = (flags & MGMT_ADV_FLAG_CONNECTABLE) || |
---|
1575 | 2002 | mgmt_get_connectable(hdev); |
---|
1576 | 2003 | |
---|
1577 | | - if (!is_advertising_allowed(hdev, connectable)) |
---|
| 2004 | + if (!is_advertising_allowed(hdev, connectable)) |
---|
1578 | 2005 | return -EPERM; |
---|
1579 | 2006 | |
---|
1580 | 2007 | /* Set require_privacy to true only when non-connectable |
---|
.. | .. |
---|
1589 | 2016 | |
---|
1590 | 2017 | memset(&cp, 0, sizeof(cp)); |
---|
1591 | 2018 | |
---|
1592 | | - memcpy(cp.min_interval, adv_interval, sizeof(cp.min_interval)); |
---|
1593 | | - memcpy(cp.max_interval, adv_interval, sizeof(cp.max_interval)); |
---|
| 2019 | + /* In ext adv set param interval is 3 octets */ |
---|
| 2020 | + hci_cpu_to_le24(hdev->le_adv_min_interval, cp.min_interval); |
---|
| 2021 | + hci_cpu_to_le24(hdev->le_adv_max_interval, cp.max_interval); |
---|
1594 | 2022 | |
---|
1595 | 2023 | secondary_adv = (flags & MGMT_ADV_FLAG_SEC_MASK); |
---|
1596 | 2024 | |
---|
.. | .. |
---|
1614 | 2042 | cp.own_addr_type = own_addr_type; |
---|
1615 | 2043 | cp.channel_map = hdev->le_adv_channel_map; |
---|
1616 | 2044 | cp.tx_power = 127; |
---|
1617 | | - cp.handle = 0; |
---|
| 2045 | + cp.handle = instance; |
---|
1618 | 2046 | |
---|
1619 | 2047 | if (flags & MGMT_ADV_FLAG_SEC_2M) { |
---|
1620 | 2048 | cp.primary_phy = HCI_ADV_PHY_1M; |
---|
.. | .. |
---|
1645 | 2073 | |
---|
1646 | 2074 | memset(&cp, 0, sizeof(cp)); |
---|
1647 | 2075 | |
---|
1648 | | - cp.handle = 0; |
---|
| 2076 | + cp.handle = instance; |
---|
1649 | 2077 | bacpy(&cp.bdaddr, &random_addr); |
---|
1650 | 2078 | |
---|
1651 | 2079 | hci_req_add(req, |
---|
.. | .. |
---|
1656 | 2084 | return 0; |
---|
1657 | 2085 | } |
---|
1658 | 2086 | |
---|
1659 | | -void __hci_req_enable_ext_advertising(struct hci_request *req) |
---|
| 2087 | +int __hci_req_enable_ext_advertising(struct hci_request *req, u8 instance) |
---|
1660 | 2088 | { |
---|
| 2089 | + struct hci_dev *hdev = req->hdev; |
---|
1661 | 2090 | struct hci_cp_le_set_ext_adv_enable *cp; |
---|
1662 | 2091 | struct hci_cp_ext_adv_set *adv_set; |
---|
1663 | 2092 | u8 data[sizeof(*cp) + sizeof(*adv_set) * 1]; |
---|
| 2093 | + struct adv_info *adv_instance; |
---|
| 2094 | + |
---|
| 2095 | + if (instance > 0) { |
---|
| 2096 | + adv_instance = hci_find_adv_instance(hdev, instance); |
---|
| 2097 | + if (!adv_instance) |
---|
| 2098 | + return -EINVAL; |
---|
| 2099 | + } else { |
---|
| 2100 | + adv_instance = NULL; |
---|
| 2101 | + } |
---|
1664 | 2102 | |
---|
1665 | 2103 | cp = (void *) data; |
---|
1666 | 2104 | adv_set = (void *) cp->data; |
---|
.. | .. |
---|
1672 | 2110 | |
---|
1673 | 2111 | memset(adv_set, 0, sizeof(*adv_set)); |
---|
1674 | 2112 | |
---|
1675 | | - adv_set->handle = 0; |
---|
| 2113 | + adv_set->handle = instance; |
---|
| 2114 | + |
---|
| 2115 | + /* Set duration per instance since controller is responsible for |
---|
| 2116 | + * scheduling it. |
---|
| 2117 | + */ |
---|
| 2118 | + if (adv_instance && adv_instance->timeout) { |
---|
| 2119 | + u16 duration = adv_instance->timeout * MSEC_PER_SEC; |
---|
| 2120 | + |
---|
| 2121 | + /* Time = N * 10 ms */ |
---|
| 2122 | + adv_set->duration = cpu_to_le16(duration / 10); |
---|
| 2123 | + } |
---|
1676 | 2124 | |
---|
1677 | 2125 | hci_req_add(req, HCI_OP_LE_SET_EXT_ADV_ENABLE, |
---|
1678 | 2126 | sizeof(*cp) + sizeof(*adv_set) * cp->num_of_sets, |
---|
1679 | 2127 | data); |
---|
| 2128 | + |
---|
| 2129 | + return 0; |
---|
| 2130 | +} |
---|
| 2131 | + |
---|
| 2132 | +int __hci_req_disable_ext_adv_instance(struct hci_request *req, u8 instance) |
---|
| 2133 | +{ |
---|
| 2134 | + struct hci_dev *hdev = req->hdev; |
---|
| 2135 | + struct hci_cp_le_set_ext_adv_enable *cp; |
---|
| 2136 | + struct hci_cp_ext_adv_set *adv_set; |
---|
| 2137 | + u8 data[sizeof(*cp) + sizeof(*adv_set) * 1]; |
---|
| 2138 | + u8 req_size; |
---|
| 2139 | + |
---|
| 2140 | + /* If request specifies an instance that doesn't exist, fail */ |
---|
| 2141 | + if (instance > 0 && !hci_find_adv_instance(hdev, instance)) |
---|
| 2142 | + return -EINVAL; |
---|
| 2143 | + |
---|
| 2144 | + memset(data, 0, sizeof(data)); |
---|
| 2145 | + |
---|
| 2146 | + cp = (void *)data; |
---|
| 2147 | + adv_set = (void *)cp->data; |
---|
| 2148 | + |
---|
| 2149 | + /* Instance 0x00 indicates all advertising instances will be disabled */ |
---|
| 2150 | + cp->num_of_sets = !!instance; |
---|
| 2151 | + cp->enable = 0x00; |
---|
| 2152 | + |
---|
| 2153 | + adv_set->handle = instance; |
---|
| 2154 | + |
---|
| 2155 | + req_size = sizeof(*cp) + sizeof(*adv_set) * cp->num_of_sets; |
---|
| 2156 | + hci_req_add(req, HCI_OP_LE_SET_EXT_ADV_ENABLE, req_size, data); |
---|
| 2157 | + |
---|
| 2158 | + return 0; |
---|
| 2159 | +} |
---|
| 2160 | + |
---|
| 2161 | +int __hci_req_remove_ext_adv_instance(struct hci_request *req, u8 instance) |
---|
| 2162 | +{ |
---|
| 2163 | + struct hci_dev *hdev = req->hdev; |
---|
| 2164 | + |
---|
| 2165 | + /* If request specifies an instance that doesn't exist, fail */ |
---|
| 2166 | + if (instance > 0 && !hci_find_adv_instance(hdev, instance)) |
---|
| 2167 | + return -EINVAL; |
---|
| 2168 | + |
---|
| 2169 | + hci_req_add(req, HCI_OP_LE_REMOVE_ADV_SET, sizeof(instance), &instance); |
---|
| 2170 | + |
---|
| 2171 | + return 0; |
---|
1680 | 2172 | } |
---|
1681 | 2173 | |
---|
1682 | 2174 | int __hci_req_start_ext_adv(struct hci_request *req, u8 instance) |
---|
1683 | 2175 | { |
---|
1684 | 2176 | struct hci_dev *hdev = req->hdev; |
---|
| 2177 | + struct adv_info *adv_instance = hci_find_adv_instance(hdev, instance); |
---|
1685 | 2178 | int err; |
---|
1686 | 2179 | |
---|
1687 | | - if (hci_dev_test_flag(hdev, HCI_LE_ADV)) |
---|
1688 | | - __hci_req_disable_advertising(req); |
---|
| 2180 | + /* If instance isn't pending, the chip knows about it, and it's safe to |
---|
| 2181 | + * disable |
---|
| 2182 | + */ |
---|
| 2183 | + if (adv_instance && !adv_instance->pending) |
---|
| 2184 | + __hci_req_disable_ext_adv_instance(req, instance); |
---|
1689 | 2185 | |
---|
1690 | 2186 | err = __hci_req_setup_ext_adv_instance(req, instance); |
---|
1691 | 2187 | if (err < 0) |
---|
1692 | 2188 | return err; |
---|
1693 | 2189 | |
---|
1694 | 2190 | __hci_req_update_scan_rsp_data(req, instance); |
---|
1695 | | - __hci_req_enable_ext_advertising(req); |
---|
| 2191 | + __hci_req_enable_ext_advertising(req, instance); |
---|
1696 | 2192 | |
---|
1697 | 2193 | return 0; |
---|
1698 | 2194 | } |
---|
.. | .. |
---|
1736 | 2232 | adv_instance->remaining_time = |
---|
1737 | 2233 | adv_instance->remaining_time - timeout; |
---|
1738 | 2234 | |
---|
1739 | | - hdev->adv_instance_timeout = timeout; |
---|
1740 | | - queue_delayed_work(hdev->req_workqueue, |
---|
| 2235 | + /* Only use work for scheduling instances with legacy advertising */ |
---|
| 2236 | + if (!ext_adv_capable(hdev)) { |
---|
| 2237 | + hdev->adv_instance_timeout = timeout; |
---|
| 2238 | + queue_delayed_work(hdev->req_workqueue, |
---|
1741 | 2239 | &hdev->adv_instance_expire, |
---|
1742 | 2240 | msecs_to_jiffies(timeout * 1000)); |
---|
| 2241 | + } |
---|
1743 | 2242 | |
---|
1744 | 2243 | /* If we're just re-scheduling the same instance again then do not |
---|
1745 | 2244 | * execute any HCI commands. This happens when a single instance is |
---|
.. | .. |
---|
1759 | 2258 | } |
---|
1760 | 2259 | |
---|
1761 | 2260 | return 0; |
---|
1762 | | -} |
---|
1763 | | - |
---|
1764 | | -static void cancel_adv_timeout(struct hci_dev *hdev) |
---|
1765 | | -{ |
---|
1766 | | - if (hdev->adv_instance_timeout) { |
---|
1767 | | - hdev->adv_instance_timeout = 0; |
---|
1768 | | - cancel_delayed_work(&hdev->adv_instance_expire); |
---|
1769 | | - } |
---|
1770 | 2261 | } |
---|
1771 | 2262 | |
---|
1772 | 2263 | /* For a single instance: |
---|
.. | .. |
---|
1830 | 2321 | hci_dev_test_flag(hdev, HCI_ADVERTISING)) |
---|
1831 | 2322 | return; |
---|
1832 | 2323 | |
---|
1833 | | - if (next_instance) |
---|
| 2324 | + if (next_instance && !ext_adv_capable(hdev)) |
---|
1834 | 2325 | __hci_req_schedule_adv_instance(req, next_instance->instance, |
---|
1835 | 2326 | false); |
---|
1836 | 2327 | } |
---|
.. | .. |
---|
1872 | 2363 | if (use_rpa) { |
---|
1873 | 2364 | int to; |
---|
1874 | 2365 | |
---|
1875 | | - *own_addr_type = ADDR_LE_DEV_RANDOM; |
---|
| 2366 | + /* If Controller supports LL Privacy use own address type is |
---|
| 2367 | + * 0x03 |
---|
| 2368 | + */ |
---|
| 2369 | + if (use_ll_privacy(hdev)) |
---|
| 2370 | + *own_addr_type = ADDR_LE_DEV_RANDOM_RESOLVED; |
---|
| 2371 | + else |
---|
| 2372 | + *own_addr_type = ADDR_LE_DEV_RANDOM; |
---|
1876 | 2373 | |
---|
1877 | 2374 | if (!hci_dev_test_and_clear_flag(hdev, HCI_RPA_EXPIRED) && |
---|
1878 | 2375 | !bacmp(&hdev->random_addr, &hdev->rpa)) |
---|
.. | .. |
---|
1977 | 2474 | return; |
---|
1978 | 2475 | |
---|
1979 | 2476 | if (mgmt_powering_down(hdev)) |
---|
| 2477 | + return; |
---|
| 2478 | + |
---|
| 2479 | + if (hdev->scanning_paused) |
---|
1980 | 2480 | return; |
---|
1981 | 2481 | |
---|
1982 | 2482 | if (hci_dev_test_flag(hdev, HCI_CONNECTABLE) || |
---|
.. | .. |
---|
2288 | 2788 | |
---|
2289 | 2789 | static int le_scan_disable(struct hci_request *req, unsigned long opt) |
---|
2290 | 2790 | { |
---|
2291 | | - hci_req_add_le_scan_disable(req); |
---|
| 2791 | + hci_req_add_le_scan_disable(req, false); |
---|
2292 | 2792 | return 0; |
---|
2293 | 2793 | } |
---|
2294 | 2794 | |
---|
.. | .. |
---|
2386 | 2886 | if (!hci_dev_test_flag(hdev, HCI_LE_SCAN)) |
---|
2387 | 2887 | return 0; |
---|
2388 | 2888 | |
---|
2389 | | - hci_req_add_le_scan_disable(req); |
---|
| 2889 | + if (hdev->scanning_paused) { |
---|
| 2890 | + bt_dev_dbg(hdev, "Scanning is paused for suspend"); |
---|
| 2891 | + return 0; |
---|
| 2892 | + } |
---|
| 2893 | + |
---|
| 2894 | + hci_req_add_le_scan_disable(req, false); |
---|
2390 | 2895 | |
---|
2391 | 2896 | if (use_ext_scan(hdev)) { |
---|
2392 | 2897 | struct hci_cp_le_set_ext_scan_enable ext_enable_cp; |
---|
.. | .. |
---|
2464 | 2969 | uint16_t interval = opt; |
---|
2465 | 2970 | struct hci_dev *hdev = req->hdev; |
---|
2466 | 2971 | u8 own_addr_type; |
---|
| 2972 | + /* White list is not used for discovery */ |
---|
| 2973 | + u8 filter_policy = 0x00; |
---|
| 2974 | + /* Discovery doesn't require controller address resolution */ |
---|
| 2975 | + bool addr_resolv = false; |
---|
2467 | 2976 | int err; |
---|
2468 | 2977 | |
---|
2469 | 2978 | BT_DBG("%s", hdev->name); |
---|
2470 | | - |
---|
2471 | | - if (hci_dev_test_flag(hdev, HCI_LE_ADV)) { |
---|
2472 | | - hci_dev_lock(hdev); |
---|
2473 | | - |
---|
2474 | | - /* Don't let discovery abort an outgoing connection attempt |
---|
2475 | | - * that's using directed advertising. |
---|
2476 | | - */ |
---|
2477 | | - if (hci_lookup_le_connect(hdev)) { |
---|
2478 | | - hci_dev_unlock(hdev); |
---|
2479 | | - return -EBUSY; |
---|
2480 | | - } |
---|
2481 | | - |
---|
2482 | | - cancel_adv_timeout(hdev); |
---|
2483 | | - hci_dev_unlock(hdev); |
---|
2484 | | - |
---|
2485 | | - __hci_req_disable_advertising(req); |
---|
2486 | | - } |
---|
2487 | 2979 | |
---|
2488 | 2980 | /* If controller is scanning, it means the background scanning is |
---|
2489 | 2981 | * running. Thus, we should temporarily stop it in order to set the |
---|
2490 | 2982 | * discovery scanning parameters. |
---|
2491 | 2983 | */ |
---|
2492 | 2984 | if (hci_dev_test_flag(hdev, HCI_LE_SCAN)) |
---|
2493 | | - hci_req_add_le_scan_disable(req); |
---|
| 2985 | + hci_req_add_le_scan_disable(req, false); |
---|
2494 | 2986 | |
---|
2495 | 2987 | /* All active scans will be done with either a resolvable private |
---|
2496 | 2988 | * address (when privacy feature has been enabled) or non-resolvable |
---|
.. | .. |
---|
2501 | 2993 | if (err < 0) |
---|
2502 | 2994 | own_addr_type = ADDR_LE_DEV_PUBLIC; |
---|
2503 | 2995 | |
---|
2504 | | - hci_req_start_scan(req, LE_SCAN_ACTIVE, interval, DISCOV_LE_SCAN_WIN, |
---|
2505 | | - own_addr_type, 0); |
---|
| 2996 | + hci_req_start_scan(req, LE_SCAN_ACTIVE, interval, |
---|
| 2997 | + hdev->le_scan_window_discovery, own_addr_type, |
---|
| 2998 | + filter_policy, addr_resolv); |
---|
2506 | 2999 | return 0; |
---|
2507 | 3000 | } |
---|
2508 | 3001 | |
---|
.. | .. |
---|
2549 | 3042 | * to do BR/EDR inquiry. |
---|
2550 | 3043 | */ |
---|
2551 | 3044 | hci_req_sync(hdev, interleaved_discov, |
---|
2552 | | - DISCOV_LE_SCAN_INT * 2, HCI_CMD_TIMEOUT, |
---|
| 3045 | + hdev->le_scan_int_discovery * 2, HCI_CMD_TIMEOUT, |
---|
2553 | 3046 | status); |
---|
2554 | 3047 | break; |
---|
2555 | 3048 | } |
---|
2556 | 3049 | |
---|
2557 | 3050 | timeout = msecs_to_jiffies(hdev->discov_interleaved_timeout); |
---|
2558 | | - hci_req_sync(hdev, active_scan, DISCOV_LE_SCAN_INT, |
---|
| 3051 | + hci_req_sync(hdev, active_scan, hdev->le_scan_int_discovery, |
---|
2559 | 3052 | HCI_CMD_TIMEOUT, status); |
---|
2560 | 3053 | break; |
---|
2561 | 3054 | case DISCOV_TYPE_LE: |
---|
2562 | 3055 | timeout = msecs_to_jiffies(DISCOV_LE_TIMEOUT); |
---|
2563 | | - hci_req_sync(hdev, active_scan, DISCOV_LE_SCAN_INT, |
---|
| 3056 | + hci_req_sync(hdev, active_scan, hdev->le_scan_int_discovery, |
---|
2564 | 3057 | HCI_CMD_TIMEOUT, status); |
---|
2565 | 3058 | break; |
---|
2566 | 3059 | default: |
---|
.. | .. |
---|
2604 | 3097 | |
---|
2605 | 3098 | if (hci_dev_test_flag(hdev, HCI_LE_SCAN)) { |
---|
2606 | 3099 | cancel_delayed_work(&hdev->le_scan_disable); |
---|
2607 | | - hci_req_add_le_scan_disable(req); |
---|
| 3100 | + hci_req_add_le_scan_disable(req, false); |
---|
2608 | 3101 | } |
---|
2609 | 3102 | |
---|
2610 | 3103 | ret = true; |
---|
2611 | 3104 | } else { |
---|
2612 | 3105 | /* Passive scanning */ |
---|
2613 | 3106 | if (hci_dev_test_flag(hdev, HCI_LE_SCAN)) { |
---|
2614 | | - hci_req_add_le_scan_disable(req); |
---|
| 3107 | + hci_req_add_le_scan_disable(req, false); |
---|
2615 | 3108 | ret = true; |
---|
2616 | 3109 | } |
---|
2617 | 3110 | } |
---|
.. | .. |
---|
2757 | 3250 | if (!ext_adv_capable(hdev)) |
---|
2758 | 3251 | __hci_req_enable_advertising(req); |
---|
2759 | 3252 | else if (!err) |
---|
2760 | | - __hci_req_enable_ext_advertising(req); |
---|
| 3253 | + __hci_req_enable_ext_advertising(req, |
---|
| 3254 | + 0x00); |
---|
2761 | 3255 | } |
---|
2762 | 3256 | } else if (!list_empty(&hdev->adv_instances)) { |
---|
2763 | 3257 | struct adv_info *adv_instance; |
---|