diff --git a/src/adapter.c b/src/adapter.c
index db2624c..f7faaa2 100644
--- a/src/adapter.c
+++ b/src/adapter.c
if (!device)
goto free;
+ if (irk_info)
+ device_set_rpa(device, true);
+
btd_device_set_temporary(device, false);
adapter_add_device(adapter, device);
adapter, NULL);
}
-#define EXP_FEAT(_uuid, _func) \
+#define EXP_FEAT(_flag, _uuid, _func) \
{ \
+ .flag = _flag, \
.uuid = _uuid, \
.func = _func, \
}
}
static const struct exp_feat {
+ uint32_t flag;
const struct mgmt_exp_uuid *uuid;
void (*func)(struct btd_adapter *adapter, uint8_t action);
} exp_table[] = {
- EXP_FEAT(&debug_uuid, exp_debug_func),
- EXP_FEAT(&le_simult_central_peripheral_uuid,
+ EXP_FEAT(EXP_FEAT_DEBUG, &debug_uuid, exp_debug_func),
+ EXP_FEAT(EXP_FEAT_LE_SIMULT_ROLES, &le_simult_central_peripheral_uuid,
le_simult_central_peripheral_func),
- EXP_FEAT(&quality_report_uuid, quality_report_func),
- EXP_FEAT(&rpa_resolution_uuid, rpa_resolution_func),
- EXP_FEAT(&codec_offload_uuid, codec_offload_func),
+ EXP_FEAT(EXP_FEAT_BQR, &quality_report_uuid, quality_report_func),
+ EXP_FEAT(EXP_FEAT_RPA_RESOLUTION, &rpa_resolution_uuid,
+ rpa_resolution_func),
+ EXP_FEAT(EXP_FEAT_CODEC_OFFLOAD, &codec_offload_uuid,
+ codec_offload_func),
};
static void read_exp_features_complete(uint8_t status, uint16_t length,
{
return (kernel_features & features) ? true : false;
}
+
+bool btd_adapter_has_exp_feature(struct btd_adapter *adapter, uint32_t feature)
+{
+ size_t i;
+
+ for (i = 0; i < ARRAY_SIZE(exp_table); i++) {
+ const struct exp_feat *feat = &exp_table[i];
+
+ if ((feat->flag & feature) && queue_find(adapter->exps, NULL,
+ feat->uuid->val))
+ return true;
+ }
+
+ return false;
+}
diff --git a/src/adapter.h b/src/adapter.h
index 35deb1d..688ed51 100644
--- a/src/adapter.h
+++ b/src/adapter.h
bool btd_le_connect_before_pairing(void);
+enum experimental_features {
+ EXP_FEAT_DEBUG = 1 << 0,
+ EXP_FEAT_LE_SIMULT_ROLES = 1 << 1,
+ EXP_FEAT_BQR = 1 << 2,
+ EXP_FEAT_RPA_RESOLUTION = 1 << 3,
+ EXP_FEAT_CODEC_OFFLOAD = 1 << 4,
+};
+
+bool btd_adapter_has_exp_feature(struct btd_adapter *adapter, uint32_t feature);
+
enum kernel_features {
KERNEL_CONN_CONTROL = 1 << 0,
KERNEL_BLOCKED_KEYS_SUPPORTED = 1 << 1,
diff --git a/src/device.c b/src/device.c
index a39eb8c..638bad0 100644
--- a/src/device.c
+++ b/src/device.c
uint8_t conn_bdaddr_type;
bdaddr_t bdaddr;
uint8_t bdaddr_type;
+ bool rpa;
char *path;
bool bredr;
bool le;
void device_set_wake_support(struct btd_device *device, bool wake_support)
{
+ if (device->rpa && !btd_adapter_has_exp_feature(device->adapter,
+ EXP_FEAT_RPA_RESOLUTION)) {
+ warn("Unable to set wake_support without RPA resolution");
+ return;
+ }
+
device->wake_support = wake_support;
/* If wake configuration has not been made yet, set the initial
DEVICE_INTERFACE, "Icon");
}
+void device_set_rpa(struct btd_device *device, bool value)
+{
+ device->rpa = value;
+}
+
void device_update_addr(struct btd_device *device, const bdaddr_t *bdaddr,
uint8_t bdaddr_type)
{
bool auto_connect = device->auto_connect;
+ device_set_rpa(device, true);
+
if (!bacmp(bdaddr, &device->bdaddr) &&
bdaddr_type == device->bdaddr_type)
return;
diff --git a/src/device.h b/src/device.h
index 9cdc0e6..5e8d1c3 100644
--- a/src/device.h
+++ b/src/device.h
bool device_is_name_resolve_allowed(struct btd_device *device);
void device_name_resolve_fail(struct btd_device *device);
void device_set_class(struct btd_device *device, uint32_t class);
+void device_set_rpa(struct btd_device *device, bool value);
void device_update_addr(struct btd_device *device, const bdaddr_t *bdaddr,
uint8_t bdaddr_type);
void device_set_bredr_support(struct btd_device *device);