mgmt.c (5c49bcce5c124406920843af65574104aaaa3309) | mgmt.c (cbbdfa6f331980c6786b4ca5df53c37b90df3246) |
---|---|
1/* 2 BlueZ - Bluetooth protocol stack for Linux 3 4 Copyright (C) 2010 Nokia Corporation 5 Copyright (C) 2011-2012 Intel Corporation 6 7 This program is free software; you can redistribute it and/or modify 8 it under the terms of the GNU General Public License version 2 as --- 781 unchanged lines hidden (view full) --- 790 791 if (test_bit(HCI_QUIRK_WIDEBAND_SPEECH_SUPPORTED, 792 &hdev->quirks)) 793 settings |= MGMT_SETTING_WIDEBAND_SPEECH; 794 } 795 796 if (lmp_le_capable(hdev)) { 797 settings |= MGMT_SETTING_LE; | 1/* 2 BlueZ - Bluetooth protocol stack for Linux 3 4 Copyright (C) 2010 Nokia Corporation 5 Copyright (C) 2011-2012 Intel Corporation 6 7 This program is free software; you can redistribute it and/or modify 8 it under the terms of the GNU General Public License version 2 as --- 781 unchanged lines hidden (view full) --- 790 791 if (test_bit(HCI_QUIRK_WIDEBAND_SPEECH_SUPPORTED, 792 &hdev->quirks)) 793 settings |= MGMT_SETTING_WIDEBAND_SPEECH; 794 } 795 796 if (lmp_le_capable(hdev)) { 797 settings |= MGMT_SETTING_LE; |
798 settings |= MGMT_SETTING_ADVERTISING; | |
799 settings |= MGMT_SETTING_SECURE_CONN; 800 settings |= MGMT_SETTING_PRIVACY; 801 settings |= MGMT_SETTING_STATIC_ADDRESS; | 798 settings |= MGMT_SETTING_SECURE_CONN; 799 settings |= MGMT_SETTING_PRIVACY; 800 settings |= MGMT_SETTING_STATIC_ADDRESS; |
801 802 /* When the experimental feature for LL Privacy support is 803 * enabled, then advertising is no longer supported. 804 */ 805 if (!hci_dev_test_flag(hdev, HCI_ENABLE_LL_PRIVACY)) 806 settings |= MGMT_SETTING_ADVERTISING; |
|
802 } 803 804 if (test_bit(HCI_QUIRK_EXTERNAL_CONFIG, &hdev->quirks) || 805 hdev->set_bdaddr) 806 settings |= MGMT_SETTING_CONFIGURATION; 807 808 settings |= MGMT_SETTING_PHY_CONFIGURATION; 809 --- 2944 unchanged lines hidden (view full) --- 3754#endif 3755 3756/* 671b10b5-42c0-4696-9227-eb28d1b049d6 */ 3757static const u8 simult_central_periph_uuid[16] = { 3758 0xd6, 0x49, 0xb0, 0xd1, 0x28, 0xeb, 0x27, 0x92, 3759 0x96, 0x46, 0xc0, 0x42, 0xb5, 0x10, 0x1b, 0x67, 3760}; 3761 | 807 } 808 809 if (test_bit(HCI_QUIRK_EXTERNAL_CONFIG, &hdev->quirks) || 810 hdev->set_bdaddr) 811 settings |= MGMT_SETTING_CONFIGURATION; 812 813 settings |= MGMT_SETTING_PHY_CONFIGURATION; 814 --- 2944 unchanged lines hidden (view full) --- 3759#endif 3760 3761/* 671b10b5-42c0-4696-9227-eb28d1b049d6 */ 3762static const u8 simult_central_periph_uuid[16] = { 3763 0xd6, 0x49, 0xb0, 0xd1, 0x28, 0xeb, 0x27, 0x92, 3764 0x96, 0x46, 0xc0, 0x42, 0xb5, 0x10, 0x1b, 0x67, 3765}; 3766 |
3767/* 15c0a148-c273-11ea-b3de-0242ac130004 */ 3768static const u8 rpa_resolution_uuid[16] = { 3769 0x04, 0x00, 0x13, 0xac, 0x42, 0x02, 0xde, 0xb3, 3770 0xea, 0x11, 0x73, 0xc2, 0x48, 0xa1, 0xc0, 0x15, 3771}; 3772 |
|
3762static int read_exp_features_info(struct sock *sk, struct hci_dev *hdev, 3763 void *data, u16 data_len) 3764{ | 3773static int read_exp_features_info(struct sock *sk, struct hci_dev *hdev, 3774 void *data, u16 data_len) 3775{ |
3765 char buf[44]; | 3776 char buf[62]; /* Enough space for 3 features */ |
3766 struct mgmt_rp_read_exp_features_info *rp = (void *)buf; 3767 u16 idx = 0; 3768 u32 flags; 3769 3770 bt_dev_dbg(hdev, "sock %p", sk); 3771 3772 memset(&buf, 0, sizeof(buf)); 3773 --- 16 unchanged lines hidden (view full) --- 3790 else 3791 flags = 0; 3792 3793 memcpy(rp->features[idx].uuid, simult_central_periph_uuid, 16); 3794 rp->features[idx].flags = cpu_to_le32(flags); 3795 idx++; 3796 } 3797 | 3777 struct mgmt_rp_read_exp_features_info *rp = (void *)buf; 3778 u16 idx = 0; 3779 u32 flags; 3780 3781 bt_dev_dbg(hdev, "sock %p", sk); 3782 3783 memset(&buf, 0, sizeof(buf)); 3784 --- 16 unchanged lines hidden (view full) --- 3801 else 3802 flags = 0; 3803 3804 memcpy(rp->features[idx].uuid, simult_central_periph_uuid, 16); 3805 rp->features[idx].flags = cpu_to_le32(flags); 3806 idx++; 3807 } 3808 |
3809 if (hdev && use_ll_privacy(hdev)) { 3810 if (hci_dev_test_flag(hdev, HCI_ENABLE_LL_PRIVACY)) 3811 flags = BIT(0) | BIT(1); 3812 else 3813 flags = BIT(1); 3814 3815 memcpy(rp->features[idx].uuid, rpa_resolution_uuid, 16); 3816 rp->features[idx].flags = cpu_to_le32(flags); 3817 idx++; 3818 } 3819 |
|
3798 rp->feature_count = cpu_to_le16(idx); 3799 3800 /* After reading the experimental features information, enable 3801 * the events to update client on any future change. 3802 */ 3803 hci_sock_set_flag(sk, HCI_MGMT_EXP_FEATURE_EVENTS); 3804 3805 return mgmt_cmd_complete(sk, hdev ? hdev->id : MGMT_INDEX_NONE, 3806 MGMT_OP_READ_EXP_FEATURES_INFO, 3807 0, rp, sizeof(*rp) + (20 * idx)); 3808} 3809 | 3820 rp->feature_count = cpu_to_le16(idx); 3821 3822 /* After reading the experimental features information, enable 3823 * the events to update client on any future change. 3824 */ 3825 hci_sock_set_flag(sk, HCI_MGMT_EXP_FEATURE_EVENTS); 3826 3827 return mgmt_cmd_complete(sk, hdev ? hdev->id : MGMT_INDEX_NONE, 3828 MGMT_OP_READ_EXP_FEATURES_INFO, 3829 0, rp, sizeof(*rp) + (20 * idx)); 3830} 3831 |
3832static int exp_ll_privacy_feature_changed(bool enabled, struct hci_dev *hdev, 3833 struct sock *skip) 3834{ 3835 struct mgmt_ev_exp_feature_changed ev; 3836 3837 memset(&ev, 0, sizeof(ev)); 3838 memcpy(ev.uuid, rpa_resolution_uuid, 16); 3839 ev.flags = cpu_to_le32((enabled ? BIT(0) : 0) | BIT(1)); 3840 3841 return mgmt_limited_event(MGMT_EV_EXP_FEATURE_CHANGED, hdev, 3842 &ev, sizeof(ev), 3843 HCI_MGMT_EXP_FEATURE_EVENTS, skip); 3844 3845} 3846 |
|
3810#ifdef CONFIG_BT_FEATURE_DEBUG 3811static int exp_debug_feature_changed(bool enabled, struct sock *skip) 3812{ 3813 struct mgmt_ev_exp_feature_changed ev; 3814 3815 memset(&ev, 0, sizeof(ev)); 3816 memcpy(ev.uuid, debug_uuid, 16); 3817 ev.flags = cpu_to_le32(enabled ? BIT(0) : 0); --- 22 unchanged lines hidden (view full) --- 3840 3841 bt_dbg_set(false); 3842 3843 if (changed) 3844 exp_debug_feature_changed(false, sk); 3845 } 3846#endif 3847 | 3847#ifdef CONFIG_BT_FEATURE_DEBUG 3848static int exp_debug_feature_changed(bool enabled, struct sock *skip) 3849{ 3850 struct mgmt_ev_exp_feature_changed ev; 3851 3852 memset(&ev, 0, sizeof(ev)); 3853 memcpy(ev.uuid, debug_uuid, 16); 3854 ev.flags = cpu_to_le32(enabled ? BIT(0) : 0); --- 22 unchanged lines hidden (view full) --- 3877 3878 bt_dbg_set(false); 3879 3880 if (changed) 3881 exp_debug_feature_changed(false, sk); 3882 } 3883#endif 3884 |
3885 if (hdev && use_ll_privacy(hdev) && !hdev_is_powered(hdev)) { 3886 bool changed = hci_dev_test_flag(hdev, 3887 HCI_ENABLE_LL_PRIVACY); 3888 3889 hci_dev_clear_flag(hdev, HCI_ENABLE_LL_PRIVACY); 3890 3891 if (changed) 3892 exp_ll_privacy_feature_changed(false, hdev, sk); 3893 } 3894 |
|
3848 hci_sock_set_flag(sk, HCI_MGMT_EXP_FEATURE_EVENTS); 3849 3850 return mgmt_cmd_complete(sk, hdev ? hdev->id : MGMT_INDEX_NONE, 3851 MGMT_OP_SET_EXP_FEATURE, 0, 3852 &rp, sizeof(rp)); 3853 } 3854 3855#ifdef CONFIG_BT_FEATURE_DEBUG --- 34 unchanged lines hidden (view full) --- 3890 3891 if (changed) 3892 exp_debug_feature_changed(val, sk); 3893 3894 return err; 3895 } 3896#endif 3897 | 3895 hci_sock_set_flag(sk, HCI_MGMT_EXP_FEATURE_EVENTS); 3896 3897 return mgmt_cmd_complete(sk, hdev ? hdev->id : MGMT_INDEX_NONE, 3898 MGMT_OP_SET_EXP_FEATURE, 0, 3899 &rp, sizeof(rp)); 3900 } 3901 3902#ifdef CONFIG_BT_FEATURE_DEBUG --- 34 unchanged lines hidden (view full) --- 3937 3938 if (changed) 3939 exp_debug_feature_changed(val, sk); 3940 3941 return err; 3942 } 3943#endif 3944 |
3945 if (!memcmp(cp->uuid, rpa_resolution_uuid, 16)) { 3946 bool val, changed; 3947 int err; 3948 u32 flags; 3949 3950 /* Command requires to use the controller index */ 3951 if (!hdev) 3952 return mgmt_cmd_status(sk, MGMT_INDEX_NONE, 3953 MGMT_OP_SET_EXP_FEATURE, 3954 MGMT_STATUS_INVALID_INDEX); 3955 3956 /* Changes can only be made when controller is powered down */ 3957 if (hdev_is_powered(hdev)) 3958 return mgmt_cmd_status(sk, hdev->id, 3959 MGMT_OP_SET_EXP_FEATURE, 3960 MGMT_STATUS_NOT_POWERED); 3961 3962 /* Parameters are limited to a single octet */ 3963 if (data_len != MGMT_SET_EXP_FEATURE_SIZE + 1) 3964 return mgmt_cmd_status(sk, hdev->id, 3965 MGMT_OP_SET_EXP_FEATURE, 3966 MGMT_STATUS_INVALID_PARAMS); 3967 3968 /* Only boolean on/off is supported */ 3969 if (cp->param[0] != 0x00 && cp->param[0] != 0x01) 3970 return mgmt_cmd_status(sk, hdev->id, 3971 MGMT_OP_SET_EXP_FEATURE, 3972 MGMT_STATUS_INVALID_PARAMS); 3973 3974 val = !!cp->param[0]; 3975 3976 if (val) { 3977 changed = !hci_dev_test_flag(hdev, 3978 HCI_ENABLE_LL_PRIVACY); 3979 hci_dev_set_flag(hdev, HCI_ENABLE_LL_PRIVACY); 3980 hci_dev_clear_flag(hdev, HCI_ADVERTISING); 3981 3982 /* Enable LL privacy + supported settings changed */ 3983 flags = BIT(0) | BIT(1); 3984 } else { 3985 changed = hci_dev_test_flag(hdev, 3986 HCI_ENABLE_LL_PRIVACY); 3987 hci_dev_clear_flag(hdev, HCI_ENABLE_LL_PRIVACY); 3988 3989 /* Disable LL privacy + supported settings changed */ 3990 flags = BIT(1); 3991 } 3992 3993 memcpy(rp.uuid, rpa_resolution_uuid, 16); 3994 rp.flags = cpu_to_le32(flags); 3995 3996 hci_sock_set_flag(sk, HCI_MGMT_EXP_FEATURE_EVENTS); 3997 3998 err = mgmt_cmd_complete(sk, hdev->id, 3999 MGMT_OP_SET_EXP_FEATURE, 0, 4000 &rp, sizeof(rp)); 4001 4002 if (changed) 4003 exp_ll_privacy_feature_changed(val, hdev, sk); 4004 4005 return err; 4006 } 4007 |
|
3898 return mgmt_cmd_status(sk, hdev ? hdev->id : MGMT_INDEX_NONE, 3899 MGMT_OP_SET_EXP_FEATURE, 3900 MGMT_STATUS_NOT_SUPPORTED); 3901} 3902 3903#define SUPPORTED_DEVICE_FLAGS() ((1U << HCI_CONN_FLAG_MAX) - 1) 3904 3905static int get_device_flags(struct sock *sk, struct hci_dev *hdev, void *data, --- 1129 unchanged lines hidden (view full) --- 5035 5036 bt_dev_dbg(hdev, "sock %p", sk); 5037 5038 status = mgmt_le_support(hdev); 5039 if (status) 5040 return mgmt_cmd_status(sk, hdev->id, MGMT_OP_SET_ADVERTISING, 5041 status); 5042 | 4008 return mgmt_cmd_status(sk, hdev ? hdev->id : MGMT_INDEX_NONE, 4009 MGMT_OP_SET_EXP_FEATURE, 4010 MGMT_STATUS_NOT_SUPPORTED); 4011} 4012 4013#define SUPPORTED_DEVICE_FLAGS() ((1U << HCI_CONN_FLAG_MAX) - 1) 4014 4015static int get_device_flags(struct sock *sk, struct hci_dev *hdev, void *data, --- 1129 unchanged lines hidden (view full) --- 5145 5146 bt_dev_dbg(hdev, "sock %p", sk); 5147 5148 status = mgmt_le_support(hdev); 5149 if (status) 5150 return mgmt_cmd_status(sk, hdev->id, MGMT_OP_SET_ADVERTISING, 5151 status); 5152 |
5153 /* Enabling the experimental LL Privay support disables support for 5154 * advertising. 5155 */ 5156 if (hci_dev_test_flag(hdev, HCI_ENABLE_LL_PRIVACY)) 5157 return mgmt_cmd_status(sk, hdev->id, MGMT_OP_SET_ADVERTISING, 5158 MGMT_STATUS_NOT_SUPPORTED); 5159 |
|
5043 if (cp->val != 0x00 && cp->val != 0x01 && cp->val != 0x02) 5044 return mgmt_cmd_status(sk, hdev->id, MGMT_OP_SET_ADVERTISING, 5045 MGMT_STATUS_INVALID_PARAMS); 5046 5047 if (hdev->advertising_paused) 5048 return mgmt_cmd_status(sk, hdev->id, MGMT_OP_SET_ADVERTISING, 5049 MGMT_STATUS_BUSY); 5050 --- 2056 unchanged lines hidden (view full) --- 7107 u8 *instance; 7108 7109 bt_dev_dbg(hdev, "sock %p", sk); 7110 7111 if (!lmp_le_capable(hdev)) 7112 return mgmt_cmd_status(sk, hdev->id, MGMT_OP_READ_ADV_FEATURES, 7113 MGMT_STATUS_REJECTED); 7114 | 5160 if (cp->val != 0x00 && cp->val != 0x01 && cp->val != 0x02) 5161 return mgmt_cmd_status(sk, hdev->id, MGMT_OP_SET_ADVERTISING, 5162 MGMT_STATUS_INVALID_PARAMS); 5163 5164 if (hdev->advertising_paused) 5165 return mgmt_cmd_status(sk, hdev->id, MGMT_OP_SET_ADVERTISING, 5166 MGMT_STATUS_BUSY); 5167 --- 2056 unchanged lines hidden (view full) --- 7224 u8 *instance; 7225 7226 bt_dev_dbg(hdev, "sock %p", sk); 7227 7228 if (!lmp_le_capable(hdev)) 7229 return mgmt_cmd_status(sk, hdev->id, MGMT_OP_READ_ADV_FEATURES, 7230 MGMT_STATUS_REJECTED); 7231 |
7232 /* Enabling the experimental LL Privay support disables support for 7233 * advertising. 7234 */ 7235 if (hci_dev_test_flag(hdev, HCI_ENABLE_LL_PRIVACY)) 7236 return mgmt_cmd_status(sk, hdev->id, MGMT_OP_SET_ADVERTISING, 7237 MGMT_STATUS_NOT_SUPPORTED); 7238 |
|
7115 hci_dev_lock(hdev); 7116 7117 rp_len = sizeof(*rp) + hdev->adv_instance_cnt; 7118 rp = kmalloc(rp_len, GFP_ATOMIC); 7119 if (!rp) { 7120 hci_dev_unlock(hdev); 7121 return -ENOMEM; 7122 } --- 187 unchanged lines hidden (view full) --- 7310 7311 bt_dev_dbg(hdev, "sock %p", sk); 7312 7313 status = mgmt_le_support(hdev); 7314 if (status) 7315 return mgmt_cmd_status(sk, hdev->id, MGMT_OP_ADD_ADVERTISING, 7316 status); 7317 | 7239 hci_dev_lock(hdev); 7240 7241 rp_len = sizeof(*rp) + hdev->adv_instance_cnt; 7242 rp = kmalloc(rp_len, GFP_ATOMIC); 7243 if (!rp) { 7244 hci_dev_unlock(hdev); 7245 return -ENOMEM; 7246 } --- 187 unchanged lines hidden (view full) --- 7434 7435 bt_dev_dbg(hdev, "sock %p", sk); 7436 7437 status = mgmt_le_support(hdev); 7438 if (status) 7439 return mgmt_cmd_status(sk, hdev->id, MGMT_OP_ADD_ADVERTISING, 7440 status); 7441 |
7442 /* Enabling the experimental LL Privay support disables support for 7443 * advertising. 7444 */ 7445 if (hci_dev_test_flag(hdev, HCI_ENABLE_LL_PRIVACY)) 7446 return mgmt_cmd_status(sk, hdev->id, MGMT_OP_SET_ADVERTISING, 7447 MGMT_STATUS_NOT_SUPPORTED); 7448 |
|
7318 if (cp->instance < 1 || cp->instance > HCI_MAX_ADV_INSTANCES) 7319 return mgmt_cmd_status(sk, hdev->id, MGMT_OP_ADD_ADVERTISING, 7320 MGMT_STATUS_INVALID_PARAMS); 7321 7322 if (data_len != sizeof(*cp) + cp->adv_data_len + cp->scan_rsp_len) 7323 return mgmt_cmd_status(sk, hdev->id, MGMT_OP_ADD_ADVERTISING, 7324 MGMT_STATUS_INVALID_PARAMS); 7325 --- 148 unchanged lines hidden (view full) --- 7474 struct mgmt_cp_remove_advertising *cp = data; 7475 struct mgmt_rp_remove_advertising rp; 7476 struct mgmt_pending_cmd *cmd; 7477 struct hci_request req; 7478 int err; 7479 7480 bt_dev_dbg(hdev, "sock %p", sk); 7481 | 7449 if (cp->instance < 1 || cp->instance > HCI_MAX_ADV_INSTANCES) 7450 return mgmt_cmd_status(sk, hdev->id, MGMT_OP_ADD_ADVERTISING, 7451 MGMT_STATUS_INVALID_PARAMS); 7452 7453 if (data_len != sizeof(*cp) + cp->adv_data_len + cp->scan_rsp_len) 7454 return mgmt_cmd_status(sk, hdev->id, MGMT_OP_ADD_ADVERTISING, 7455 MGMT_STATUS_INVALID_PARAMS); 7456 --- 148 unchanged lines hidden (view full) --- 7605 struct mgmt_cp_remove_advertising *cp = data; 7606 struct mgmt_rp_remove_advertising rp; 7607 struct mgmt_pending_cmd *cmd; 7608 struct hci_request req; 7609 int err; 7610 7611 bt_dev_dbg(hdev, "sock %p", sk); 7612 |
7613 /* Enabling the experimental LL Privay support disables support for 7614 * advertising. 7615 */ 7616 if (hci_dev_test_flag(hdev, HCI_ENABLE_LL_PRIVACY)) 7617 return mgmt_cmd_status(sk, hdev->id, MGMT_OP_SET_ADVERTISING, 7618 MGMT_STATUS_NOT_SUPPORTED); 7619 |
|
7482 hci_dev_lock(hdev); 7483 7484 if (cp->instance && !hci_find_adv_instance(hdev, cp->instance)) { 7485 err = mgmt_cmd_status(sk, hdev->id, 7486 MGMT_OP_REMOVE_ADVERTISING, 7487 MGMT_STATUS_INVALID_PARAMS); 7488 goto unlock; 7489 } --- 1259 unchanged lines hidden --- | 7620 hci_dev_lock(hdev); 7621 7622 if (cp->instance && !hci_find_adv_instance(hdev, cp->instance)) { 7623 err = mgmt_cmd_status(sk, hdev->id, 7624 MGMT_OP_REMOVE_ADVERTISING, 7625 MGMT_STATUS_INVALID_PARAMS); 7626 goto unlock; 7627 } --- 1259 unchanged lines hidden --- |