mirror of
https://mirrors.bfsu.edu.cn/git/linux.git
synced 2024-12-05 01:54:09 +08:00
Bluetooth: refactor set_exp_feature with a feature table
This patch refactors the set_exp_feature with a feature table consisting of UUIDs and the corresponding callback functions. In this way, a new experimental feature setting function can be simply added with its UUID and callback function. Signed-off-by: Joseph Hwang <josephsih@chromium.org> Signed-off-by: Luiz Augusto von Dentz <luiz.von.dentz@intel.com>
This commit is contained in:
parent
76a56bbd81
commit
93fb70bc11
@ -3892,15 +3892,18 @@ static int exp_debug_feature_changed(bool enabled, struct sock *skip)
|
||||
}
|
||||
#endif
|
||||
|
||||
static int set_exp_feature(struct sock *sk, struct hci_dev *hdev,
|
||||
void *data, u16 data_len)
|
||||
#define EXP_FEAT(_uuid, _set_func) \
|
||||
{ \
|
||||
.uuid = _uuid, \
|
||||
.set_func = _set_func, \
|
||||
}
|
||||
|
||||
/* The zero key uuid is special. Multiple exp features are set through it. */
|
||||
static int set_zero_key_func(struct sock *sk, struct hci_dev *hdev,
|
||||
struct mgmt_cp_set_exp_feature *cp, u16 data_len)
|
||||
{
|
||||
struct mgmt_cp_set_exp_feature *cp = data;
|
||||
struct mgmt_rp_set_exp_feature rp;
|
||||
|
||||
bt_dev_dbg(hdev, "sock %p", sk);
|
||||
|
||||
if (!memcmp(cp->uuid, ZERO_KEY, 16)) {
|
||||
memset(rp.uuid, 0, 16);
|
||||
rp.flags = cpu_to_le32(0);
|
||||
|
||||
@ -3916,8 +3919,7 @@ static int set_exp_feature(struct sock *sk, struct hci_dev *hdev,
|
||||
#endif
|
||||
|
||||
if (hdev && use_ll_privacy(hdev) && !hdev_is_powered(hdev)) {
|
||||
bool changed = hci_dev_test_flag(hdev,
|
||||
HCI_ENABLE_LL_PRIVACY);
|
||||
bool changed = hci_dev_test_flag(hdev, HCI_ENABLE_LL_PRIVACY);
|
||||
|
||||
hci_dev_clear_flag(hdev, HCI_ENABLE_LL_PRIVACY);
|
||||
|
||||
@ -3933,7 +3935,11 @@ static int set_exp_feature(struct sock *sk, struct hci_dev *hdev,
|
||||
}
|
||||
|
||||
#ifdef CONFIG_BT_FEATURE_DEBUG
|
||||
if (!memcmp(cp->uuid, debug_uuid, 16)) {
|
||||
static int set_debug_func(struct sock *sk, struct hci_dev *hdev,
|
||||
struct mgmt_cp_set_exp_feature *cp, u16 data_len)
|
||||
{
|
||||
struct mgmt_rp_set_exp_feature rp;
|
||||
|
||||
bool val, changed;
|
||||
int err;
|
||||
|
||||
@ -3975,7 +3981,11 @@ static int set_exp_feature(struct sock *sk, struct hci_dev *hdev,
|
||||
}
|
||||
#endif
|
||||
|
||||
if (!memcmp(cp->uuid, rpa_resolution_uuid, 16)) {
|
||||
static int set_rpa_resolution_func(struct sock *sk, struct hci_dev *hdev,
|
||||
struct mgmt_cp_set_exp_feature *cp,
|
||||
u16 data_len)
|
||||
{
|
||||
struct mgmt_rp_set_exp_feature rp;
|
||||
bool val, changed;
|
||||
int err;
|
||||
u32 flags;
|
||||
@ -4007,16 +4017,14 @@ static int set_exp_feature(struct sock *sk, struct hci_dev *hdev,
|
||||
val = !!cp->param[0];
|
||||
|
||||
if (val) {
|
||||
changed = !hci_dev_test_flag(hdev,
|
||||
HCI_ENABLE_LL_PRIVACY);
|
||||
changed = !hci_dev_test_flag(hdev, HCI_ENABLE_LL_PRIVACY);
|
||||
hci_dev_set_flag(hdev, HCI_ENABLE_LL_PRIVACY);
|
||||
hci_dev_clear_flag(hdev, HCI_ADVERTISING);
|
||||
|
||||
/* Enable LL privacy + supported settings changed */
|
||||
flags = BIT(0) | BIT(1);
|
||||
} else {
|
||||
changed = hci_dev_test_flag(hdev,
|
||||
HCI_ENABLE_LL_PRIVACY);
|
||||
changed = hci_dev_test_flag(hdev, HCI_ENABLE_LL_PRIVACY);
|
||||
hci_dev_clear_flag(hdev, HCI_ENABLE_LL_PRIVACY);
|
||||
|
||||
/* Disable LL privacy + supported settings changed */
|
||||
@ -4038,6 +4046,34 @@ static int set_exp_feature(struct sock *sk, struct hci_dev *hdev,
|
||||
return err;
|
||||
}
|
||||
|
||||
static const struct mgmt_exp_feature {
|
||||
const u8 *uuid;
|
||||
int (*set_func)(struct sock *sk, struct hci_dev *hdev,
|
||||
struct mgmt_cp_set_exp_feature *cp, u16 data_len);
|
||||
} exp_features[] = {
|
||||
EXP_FEAT(ZERO_KEY, set_zero_key_func),
|
||||
#ifdef CONFIG_BT_FEATURE_DEBUG
|
||||
EXP_FEAT(debug_uuid, set_debug_func),
|
||||
#endif
|
||||
EXP_FEAT(rpa_resolution_uuid, set_rpa_resolution_func),
|
||||
|
||||
/* end with a null feature */
|
||||
EXP_FEAT(NULL, NULL)
|
||||
};
|
||||
|
||||
static int set_exp_feature(struct sock *sk, struct hci_dev *hdev,
|
||||
void *data, u16 data_len)
|
||||
{
|
||||
struct mgmt_cp_set_exp_feature *cp = data;
|
||||
size_t i = 0;
|
||||
|
||||
bt_dev_dbg(hdev, "sock %p", sk);
|
||||
|
||||
for (i = 0; exp_features[i].uuid; i++) {
|
||||
if (!memcmp(cp->uuid, exp_features[i].uuid, 16))
|
||||
return exp_features[i].set_func(sk, hdev, cp, data_len);
|
||||
}
|
||||
|
||||
return mgmt_cmd_status(sk, hdev ? hdev->id : MGMT_INDEX_NONE,
|
||||
MGMT_OP_SET_EXP_FEATURE,
|
||||
MGMT_STATUS_NOT_SUPPORTED);
|
||||
|
Loading…
Reference in New Issue
Block a user