summaryrefslogtreecommitdiff
path: root/src/main.c
diff options
context:
space:
mode:
authorLuiz Augusto von Dentz <luiz.von.dentz@intel.com>2021-09-07 14:05:38 -0700
committerLuiz Augusto von Dentz <luiz.von.dentz@intel.com>2021-09-08 14:12:58 -0700
commit3c7823a1f575447a4c1f74b7ad8e88319f148ad0 (patch)
tree6fe5d87146261f0854734b04d7397a63190f8914 /src/main.c
parentb84f294cb151e344cd68a295ff1efb905177730a (diff)
downloadbluez-3c7823a1f575447a4c1f74b7ad8e88319f148ad0.tar.gz
main.conf: Allow passing a list of UUIDs to Experimental
This allows the user to enable a subset of the experimental features to be enabled instead of all of them and also change -E to work in the same way so a list of UUIDs can also be given at the command line.
Diffstat (limited to 'src/main.c')
-rw-r--r--src/main.c108
1 files changed, 100 insertions, 8 deletions
diff --git a/src/main.c b/src/main.c
index bf8b8dca7..5ca8d5644 100644
--- a/src/main.c
+++ b/src/main.c
@@ -42,6 +42,7 @@
#include "shared/att-types.h"
#include "shared/mainloop.h"
#include "shared/timeout.h"
+#include "shared/queue.h"
#include "lib/uuid.h"
#include "shared/util.h"
#include "btd.h"
@@ -545,10 +546,78 @@ static void parse_le_config(GKeyFile *config)
parse_mode_config(config, "LE", params, ARRAY_SIZE(params));
}
+static bool match_experimental(const void *data, const void *match_data)
+{
+ const char *value = data;
+ const char *uuid = match_data;
+
+ if (!strcmp(value, "*"))
+ return true;
+
+ return !strcasecmp(value, uuid);
+}
+
+bool btd_experimental_enabled(const char *uuid)
+{
+ if (!btd_opts.experimental)
+ false;
+
+ return queue_find(btd_opts.experimental, match_experimental, uuid);
+}
+
+static const char *valid_uuids[] = {
+ "d4992530-b9ec-469f-ab01-6c481c47da1c",
+ "671b10b5-42c0-4696-9227-eb28d1b049d6",
+ "15c0a148-c273-11ea-b3de-0242ac130004",
+ "330859bc-7506-492d-9370-9a6f0614037f",
+ "a6695ace-ee7f-4fb9-881a-5fac66c629af",
+ "*"
+};
+
+static void btd_parse_experimental(char **list)
+{
+ int i;
+
+ if (btd_opts.experimental) {
+ warn("Unable to parse Experimental: list already set");
+ return;
+ }
+
+ btd_opts.experimental = queue_new();
+
+ for (i = 0; list[i]; i++) {
+ size_t j;
+ const char *uuid = list[i];
+
+ if (!strcasecmp("false", uuid) || !strcasecmp("off", uuid)) {
+ queue_destroy(btd_opts.experimental, free);
+ btd_opts.experimental = NULL;
+ }
+
+ if (!strcasecmp("true", uuid) || !strcasecmp("on", uuid))
+ uuid = "*";
+
+ for (j = 0; j < ARRAY_SIZE(valid_uuids); j++) {
+ if (!strcasecmp(valid_uuids[j], uuid))
+ break;
+ }
+
+ /* Ignored if UUID is considered invalid */
+ if (j == ARRAY_SIZE(valid_uuids)) {
+ warn("Invalid Experimental UUID: %s", uuid);
+ continue;
+ }
+
+ DBG("%s", uuid);
+
+ queue_push_tail(btd_opts.experimental, strdup(uuid));
+ }
+}
+
static void parse_config(GKeyFile *config)
{
GError *err = NULL;
- char *str;
+ char *str, **strlist;
int val;
gboolean boolean;
@@ -722,12 +791,14 @@ static void parse_config(GKeyFile *config)
else
btd_opts.refresh_discovery = boolean;
- boolean = g_key_file_get_boolean(config, "General",
- "Experimental", &err);
+ strlist = g_key_file_get_string_list(config, "General", "Experimental",
+ NULL, &err);
if (err)
g_clear_error(&err);
- else
- btd_opts.experimental = boolean;
+ else {
+ btd_parse_experimental(strlist);
+ g_strfreev(strlist);
+ }
str = g_key_file_get_string(config, "GATT", "Cache", &err);
if (err) {
@@ -840,7 +911,6 @@ static void init_defaults(void)
btd_opts.name_resolv = TRUE;
btd_opts.debug_keys = FALSE;
btd_opts.refresh_discovery = TRUE;
- btd_opts.experimental = false;
btd_opts.defaults.num_entries = 0;
btd_opts.defaults.br.page_scan_type = 0xFFFF;
@@ -993,6 +1063,24 @@ static gboolean parse_debug(const char *key, const char *value,
return TRUE;
}
+static gboolean parse_experimental(const char *key, const char *value,
+ gpointer user_data, GError **error)
+{
+ char **strlist;
+
+ if (value) {
+ strlist = g_strsplit(value, ",", -1);
+ btd_parse_experimental(strlist);
+ g_strfreev(strlist);
+ } else {
+ if (!btd_opts.experimental)
+ btd_opts.experimental = queue_new();
+ queue_push_head(btd_opts.experimental, strdup("*"));
+ }
+
+ return TRUE;
+}
+
static GOptionEntry options[] = {
{ "debug", 'd', G_OPTION_FLAG_OPTIONAL_ARG,
G_OPTION_ARG_CALLBACK, parse_debug,
@@ -1005,8 +1093,9 @@ static GOptionEntry options[] = {
"Specify an explicit path to the config file", "FILE"},
{ "compat", 'C', 0, G_OPTION_ARG_NONE, &option_compat,
"Provide deprecated command line interfaces" },
- { "experimental", 'E', 0, G_OPTION_ARG_NONE, &btd_opts.experimental,
- "Enable experimental interfaces" },
+ { "experimental", 'E', G_OPTION_FLAG_OPTIONAL_ARG,
+ G_OPTION_ARG_CALLBACK, parse_experimental,
+ "Enable experimental features/interfaces" },
{ "nodetach", 'n', G_OPTION_FLAG_REVERSE,
G_OPTION_ARG_NONE, &option_detach,
"Run with logging in foreground" },
@@ -1135,6 +1224,9 @@ int main(int argc, char *argv[])
if (btd_opts.mode != BT_MODE_LE)
stop_sdp_server();
+ if (btd_opts.experimental)
+ queue_destroy(btd_opts.experimental, free);
+
if (main_conf)
g_key_file_free(main_conf);