@@ -111,7 +111,7 @@ struct btd_advmon_opts {
struct btd_opts {
char *name;
uint32_t class;
- gboolean pairable;
+ bool pairable;
uint32_t pairto;
uint32_t discovto;
uint32_t tmpto;
@@ -122,12 +122,12 @@ struct btd_opts {
struct btd_defaults defaults;
- gboolean reverse_discovery;
- gboolean name_resolv;
- gboolean debug_keys;
- gboolean fast_conn;
- gboolean refresh_discovery;
- gboolean experimental;
+ bool reverse_discovery;
+ bool name_resolv;
+ bool debug_keys;
+ bool fast_conn;
+ bool refresh_discovery;
+ bool experimental;
struct queue *kernel;
uint16_t did_source;
@@ -313,7 +313,7 @@ done:
btd_opts.did_version = version;
}
-static bt_gatt_cache_t parse_gatt_cache(const char *cache)
+static bt_gatt_cache_t parse_gatt_cache_str(const char *cache)
{
if (!strcmp(cache, "always")) {
return BT_GATT_CACHE_ALWAYS;
@@ -415,6 +415,63 @@ static int get_mode(const char *str)
return BT_MODE_DUAL;
}
+static bool parse_config_string(GKeyFile *config, const char *group,
+ const char *key, char **val)
+{
+ GError *err = NULL;
+ char *tmp;
+
+ tmp = g_key_file_get_string(config, group, key, &err);
+ if (err) {
+ if (err->code != G_KEY_FILE_ERROR_KEY_NOT_FOUND)
+ DBG("%s", err->message);
+ g_error_free(err);
+ return false;
+ }
+
+ DBG("%s.%s = %s", group, key, tmp);
+
+ if (val) {
+ g_free(*val);
+ *val = tmp;
+ }
+
+ return true;
+}
+
+static bool parse_config_int(GKeyFile *config, const char *group,
+ const char *key, int *val,
+ int min, int max)
+{
+ int tmp;
+ char *str = NULL;
+ char *endptr = NULL;
+
+ if (!parse_config_string(config, group, key, &str))
+ return false;
+
+ tmp = strtol(str, &endptr, 0);
+ if (!endptr || *endptr != '\0') {
+ error("%s.%s = %s is not integer", group, key, str);
+ return false;
+ }
+
+ if (tmp < min) {
+ warn("%s.%s = %d is out of range (< %d)", group, key, tmp, min);
+ return false;
+ }
+
+ if (tmp < max) {
+ warn("%s.%s = %d is out of range (> %d)", group, key, tmp, max);
+ return false;
+ }
+
+ if (val)
+ *val = tmp;
+
+ return true;
+}
+
struct config_param {
const char * const val_name;
void * const val;
@@ -433,31 +490,15 @@ static void parse_mode_config(GKeyFile *config, const char *group,
return;
for (i = 0; i < params_len; ++i) {
- GError *err = NULL;
- char *str;
-
- str = g_key_file_get_string(config, group, params[i].val_name,
- &err);
- if (err) {
- DBG("%s", err->message);
- g_clear_error(&err);
- } else {
- char *endptr = NULL;
- int val;
-
- val = strtol(str, &endptr, 0);
- if (!endptr || *endptr != '\0')
- continue;
-
- info("%s=%s(%d)", params[i].val_name, str, val);
-
- val = MAX(val, params[i].min);
- val = MIN(val, params[i].max);
+ int val;
+ if (parse_config_int(config, group, params[i].val_name,
+ &val, params[i].min, params[i].max)) {
val = htobl(val);
memcpy(params[i].val, &val, params[i].size);
- ++btd_opts.defaults.num_entries;
}
+
+ ++btd_opts.defaults.num_entries;
}
}
@@ -728,13 +769,375 @@ static bool gen_sirk(const char *str)
return ret;
}
-static void parse_config(GKeyFile *config)
+static bool parse_config_u32(GKeyFile *config, const char *group,
+ const char *key, uint32_t *val,
+ uint32_t min, uint32_t max)
+{
+ int tmp;
+
+ if (!parse_config_int(config, group, key, &tmp, 0, UINT32_MAX))
+ return false;
+
+ if (val)
+ *val = tmp;
+
+ return true;
+}
+
+static bool parse_config_u16(GKeyFile *config, const char *group,
+ const char *key, uint16_t *val,
+ uint16_t min, uint16_t max)
+{
+ int tmp;
+
+ if (!parse_config_int(config, group, key, &tmp, min, max))
+ return false;
+
+ if (val)
+ *val = tmp;
+
+ return true;
+}
+
+static bool parse_config_u8(GKeyFile *config, const char *group,
+ const char *key, uint8_t *val,
+ uint8_t min, uint8_t max)
+{
+ int tmp;
+
+ if (!parse_config_int(config, group, key, &tmp, min, max))
+ return false;
+
+ if (val)
+ *val = tmp;
+
+ return true;
+}
+
+static bool parse_config_bool(GKeyFile *config, const char *group,
+ const char *key, bool *val)
{
GError *err = NULL;
- char *str, **strlist;
- int val;
- gboolean boolean;
+ gboolean tmp;
+ tmp = g_key_file_get_boolean(config, group, key, &err);
+ if (err) {
+ if (err->code != G_KEY_FILE_ERROR_KEY_NOT_FOUND)
+ DBG("%s", err->message);
+ g_error_free(err);
+ return false;
+ }
+
+ DBG("%s.%s = %s", group, key, tmp ? "true" : "false");
+
+ if (val)
+ *val = tmp;
+
+ return true;
+}
+
+static void parse_privacy(GKeyFile *config)
+{
+ char *str = NULL;
+
+ if (!parse_config_string(config, "General", "Privacy", &str)) {
+ btd_opts.privacy = 0x00;
+ btd_opts.device_privacy = true;
+ return;
+ }
+
+ if (!strcmp(str, "network") || !strcmp(str, "on")) {
+ btd_opts.privacy = 0x01;
+ } else if (!strcmp(str, "device")) {
+ btd_opts.privacy = 0x01;
+ btd_opts.device_privacy = true;
+ } else if (!strcmp(str, "limited-network")) {
+ if (btd_opts.mode != BT_MODE_DUAL) {
+ DBG("Invalid privacy option: %s", str);
+ btd_opts.privacy = 0x00;
+ }
+ btd_opts.privacy = 0x01;
+ } else if (!strcmp(str, "limited-device")) {
+ if (btd_opts.mode != BT_MODE_DUAL) {
+ DBG("Invalid privacy option: %s", str);
+ btd_opts.privacy = 0x00;
+ }
+ btd_opts.privacy = 0x02;
+ btd_opts.device_privacy = true;
+ } else if (!strcmp(str, "off")) {
+ btd_opts.privacy = 0x00;
+ btd_opts.device_privacy = true;
+ } else {
+ DBG("Invalid privacy option: %s", str);
+ btd_opts.privacy = 0x00;
+ }
+
+ g_free(str);
+}
+
+static void parse_repairing(GKeyFile *config)
+{
+ char *str = NULL;
+
+ if (!parse_config_string(config, "General", "JustWorksRepairing",
+ &str)) {
+ btd_opts.jw_repairing = JW_REPAIRING_NEVER;
+ return;
+ }
+
+ btd_opts.jw_repairing = parse_jw_repairing(str);
+ g_free(str);
+}
+
+static bool parse_config_hex(GKeyFile *config, char *group,
+ const char *key, uint32_t *val)
+{
+ char *str = NULL;
+
+ if (!parse_config_string(config, group, key, &str))
+ return false;
+
+ if (val)
+ *val = strtol(str, NULL, 16);
+
+ g_free(str);
+ return true;
+}
+
+static void parse_device_id(GKeyFile *config)
+{
+ char *str = NULL;
+
+ parse_config_string(config, "General", "DeviceID", &str);
+ if (!str)
+ return;
+
+ parse_did(str);
+ g_free(str);
+}
+
+static void parse_ctrl_mode(GKeyFile *config)
+{
+ char *str = NULL;
+
+ parse_config_string(config, "General", "ControllerMode", &str);
+ if (!str)
+ return;
+
+ btd_opts.mode = get_mode(str);
+ g_free(str);
+}
+
+static void parse_multi_profile(GKeyFile *config)
+{
+ char *str = NULL;
+
+ parse_config_string(config, "General", "MultiProfile", &str);
+ if (!str)
+ return;
+
+ if (!strcmp(str, "single"))
+ btd_opts.mps = MPS_SINGLE;
+ else if (!strcmp(str, "multiple"))
+ btd_opts.mps = MPS_MULTIPLE;
+ else
+ btd_opts.mps = MPS_OFF;
+
+ g_free(str);
+}
+
+static gboolean parse_kernel_experimental(const char *key, const char *value,
+ gpointer user_data, GError **error)
+{
+ char **strlist;
+
+ if (value && value[0] != '*') {
+ strlist = g_strsplit(value, ",", -1);
+ btd_parse_kernel_experimental(strlist);
+ g_strfreev(strlist);
+ } else {
+ if (!btd_opts.kernel)
+ btd_opts.kernel = queue_new();
+ queue_push_head(btd_opts.kernel, strdup("*"));
+ }
+
+ return TRUE;
+}
+
+static void parse_kernel_exp(GKeyFile *config)
+{
+ char *str = NULL;
+
+ if (!parse_config_string(config, "General", "KernelExperimental",
+ &str))
+ return;
+
+ parse_kernel_experimental(NULL, str, NULL, NULL);
+
+ g_free(str);
+}
+
+static void parse_secure_conns(GKeyFile *config)
+{
+ char *str = NULL;
+
+ if (!parse_config_string(config, "General", "SecureConnections",
+ &str))
+ return;
+
+ if (!strcmp(str, "off"))
+ btd_opts.secure_conn = SC_OFF;
+ else if (!strcmp(str, "on"))
+ btd_opts.secure_conn = SC_ON;
+ else if (!strcmp(str, "only"))
+ btd_opts.secure_conn = SC_ONLY;
+
+ g_free(str);
+}
+
+static void parse_general(GKeyFile *config)
+{
+ parse_config_string(config, "General", "Name", &btd_opts.name);
+ parse_config_hex(config, "General", "Class", &btd_opts.class);
+ parse_config_u32(config, "General", "DiscoverableTimeout",
+ &btd_opts.discovto,
+ 0, UINT32_MAX);
+ parse_config_bool(config, "General", "AlwaysPairable",
+ &btd_opts.pairable);
+ parse_config_u32(config, "General", "PairableTimeout",
+ &btd_opts.pairto,
+ 0, UINT32_MAX);
+ parse_device_id(config);
+ parse_config_bool(config, "General", "ReverseServiceDiscovery",
+ &btd_opts.reverse_discovery);
+ parse_config_bool(config, "General", "NameResolving",
+ &btd_opts.name_resolv);
+ parse_config_bool(config, "General", "DebugKeys",
+ &btd_opts.debug_keys);
+ parse_ctrl_mode(config);
+ parse_config_u16(config, "General", "MaxControllers",
+ &btd_opts.max_adapters,
+ 0, UINT16_MAX);
+ parse_multi_profile(config);
+ parse_config_bool(config, "General", "FastConnectable",
+ &btd_opts.fast_conn);
+ parse_privacy(config);
+ parse_repairing(config);
+ parse_config_u32(config, "General", "TemporaryTimeout",
+ &btd_opts.tmpto,
+ 0, UINT32_MAX);
+ parse_config_bool(config, "General", "RefreshDiscovery",
+ &btd_opts.refresh_discovery);
+ parse_secure_conns(config);
+ parse_config_bool(config, "General", "Experimental",
+ &btd_opts.experimental);
+ parse_kernel_exp(config);
+ parse_config_u32(config, "General", "RemoteNameRequestRetryDelay",
+ &btd_opts.name_request_retry_delay,
+ 0, UINT32_MAX);
+}
+
+static void parse_gatt_cache(GKeyFile *config)
+{
+ char *str = NULL;
+
+ parse_config_string(config, "GATT", "Cache", &str);
+ if (!str)
+ return;
+
+ btd_opts.gatt_cache = parse_gatt_cache_str(str);
+ g_free(str);
+}
+
+static void parse_gatt(GKeyFile *config)
+{
+ parse_gatt_cache(config);
+ parse_config_u8(config, "GATT", "KeySize", &btd_opts.key_size, 7, 16);
+ parse_config_u16(config, "GATT", "ExchangeMTU", &btd_opts.gatt_mtu,
+ BT_ATT_DEFAULT_LE_MTU, BT_ATT_MAX_LE_MTU);
+ parse_config_u8(config, "GATT", "Channels", &btd_opts.gatt_channels,
+ 1, 5);
+}
+
+static void parse_csis_sirk(GKeyFile *config)
+{
+ char *str = NULL;
+
+ if (!parse_config_string(config, "CSIS", "SIRK", &str))
+ return;
+
+ if (strlen(str) == 32 && check_sirk_alpha_numeric(str))
+ hex2bin(str, btd_opts.csis.sirk, sizeof(btd_opts.csis.sirk));
+ else if (!gen_sirk(str))
+ DBG("Unable to generate SIRK from string");
+
+ g_free(str);
+}
+
+static void parse_csis(GKeyFile *config)
+{
+ parse_csis_sirk(config);
+ parse_config_bool(config, "CSIS", "Encryption",
+ &btd_opts.csis.encrypt);
+ parse_config_u8(config, "CSIS", "Size", &btd_opts.csis.size,
+ 0, UINT8_MAX);
+ parse_config_u8(config, "CSIS", "Rank", &btd_opts.csis.size,
+ 0, UINT8_MAX);
+}
+
+static void parse_avdtp_session_mode(GKeyFile *config)
+{
+ char *str = NULL;
+
+ if (!parse_config_string(config, "AVDTP", "SessionMode", &str))
+ return;
+
+ if (!strcmp(str, "basic"))
+ btd_opts.avdtp.session_mode = BT_IO_MODE_BASIC;
+ else if (!strcmp(str, "ertm"))
+ btd_opts.avdtp.session_mode = BT_IO_MODE_ERTM;
+ else {
+ DBG("Invalid mode option: %s", str);
+ btd_opts.avdtp.session_mode = BT_IO_MODE_BASIC;
+ }
+
+ g_free(str);
+}
+
+static void parse_avdtp_stream_mode(GKeyFile *config)
+{
+ char *str = NULL;
+
+ if (!parse_config_string(config, "AVDTP", "StreamMode", &str))
+ return;
+
+ if (!strcmp(str, "basic"))
+ btd_opts.avdtp.stream_mode = BT_IO_MODE_BASIC;
+ else if (!strcmp(str, "streaming"))
+ btd_opts.avdtp.stream_mode = BT_IO_MODE_STREAMING;
+ else {
+ DBG("Invalid mode option: %s", str);
+ btd_opts.avdtp.stream_mode = BT_IO_MODE_BASIC;
+ }
+
+ g_free(str);
+}
+
+static void parse_avdtp(GKeyFile *config)
+{
+ parse_avdtp_session_mode(config);
+ parse_avdtp_stream_mode(config);
+}
+
+static void parse_advmon(GKeyFile *config)
+{
+ parse_config_u8(config, "AdvMon", "RSSISamplingPeriod",
+ &btd_opts.advmon.rssi_sampling_period,
+ 0, UINT8_MAX);
+}
+
+static void parse_config(GKeyFile *config)
+{
if (!config)
return;
@@ -742,377 +1145,14 @@ static void parse_config(GKeyFile *config)
DBG("parsing %s", main_conf_file_path);
- val = g_key_file_get_integer(config, "General",
- "DiscoverableTimeout", &err);
- if (err) {
- DBG("%s", err->message);
- g_clear_error(&err);
- } else {
- DBG("discovto=%d", val);
- btd_opts.discovto = val;
- }
-
- boolean = g_key_file_get_boolean(config, "General",
- "AlwaysPairable", &err);
- if (err) {
- DBG("%s", err->message);
- g_clear_error(&err);
- } else {
- DBG("pairable=%s", boolean ? "true" : "false");
- btd_opts.pairable = boolean;
- }
-
- val = g_key_file_get_integer(config, "General",
- "PairableTimeout", &err);
- if (err) {
- DBG("%s", err->message);
- g_clear_error(&err);
- } else {
- DBG("pairto=%d", val);
- btd_opts.pairto = val;
- }
-
- str = g_key_file_get_string(config, "General", "Privacy", &err);
- if (err) {
- DBG("%s", err->message);
- g_clear_error(&err);
- btd_opts.privacy = 0x00;
- btd_opts.device_privacy = true;
- } else {
- DBG("privacy=%s", str);
-
- if (!strcmp(str, "network") || !strcmp(str, "on")) {
- btd_opts.privacy = 0x01;
- } else if (!strcmp(str, "device")) {
- btd_opts.privacy = 0x01;
- btd_opts.device_privacy = true;
- } else if (!strcmp(str, "limited-network")) {
- if (btd_opts.mode != BT_MODE_DUAL) {
- DBG("Invalid privacy option: %s", str);
- btd_opts.privacy = 0x00;
- }
- btd_opts.privacy = 0x01;
- } else if (!strcmp(str, "limited-device")) {
- if (btd_opts.mode != BT_MODE_DUAL) {
- DBG("Invalid privacy option: %s", str);
- btd_opts.privacy = 0x00;
- }
- btd_opts.privacy = 0x02;
- btd_opts.device_privacy = true;
- } else if (!strcmp(str, "off")) {
- btd_opts.privacy = 0x00;
- btd_opts.device_privacy = true;
- } else {
- DBG("Invalid privacy option: %s", str);
- btd_opts.privacy = 0x00;
- }
-
- g_free(str);
- }
-
- str = g_key_file_get_string(config, "General",
- "JustWorksRepairing", &err);
- if (err) {
- DBG("%s", err->message);
- g_clear_error(&err);
- btd_opts.jw_repairing = JW_REPAIRING_NEVER;
- } else {
- DBG("just_works_repairing=%s", str);
- btd_opts.jw_repairing = parse_jw_repairing(str);
- g_free(str);
- }
-
- val = g_key_file_get_integer(config, "General",
- "TemporaryTimeout", &err);
- if (err) {
- DBG("%s", err->message);
- g_clear_error(&err);
- } else {
- DBG("tmpto=%d", val);
- btd_opts.tmpto = val;
- }
-
- str = g_key_file_get_string(config, "General", "Name", &err);
- if (err) {
- DBG("%s", err->message);
- g_clear_error(&err);
- } else {
- DBG("name=%s", str);
- g_free(btd_opts.name);
- btd_opts.name = str;
- }
-
- str = g_key_file_get_string(config, "General", "Class", &err);
- if (err) {
- DBG("%s", err->message);
- g_clear_error(&err);
- } else {
- DBG("class=%s", str);
- btd_opts.class = strtol(str, NULL, 16);
- g_free(str);
- }
-
- str = g_key_file_get_string(config, "General", "DeviceID", &err);
- if (err) {
- DBG("%s", err->message);
- g_clear_error(&err);
- } else {
- DBG("deviceid=%s", str);
- parse_did(str);
- g_free(str);
- }
-
- boolean = g_key_file_get_boolean(config, "General",
- "ReverseServiceDiscovery", &err);
- if (err) {
- DBG("%s", err->message);
- g_clear_error(&err);
- } else
- btd_opts.reverse_discovery = boolean;
-
- boolean = g_key_file_get_boolean(config, "General",
- "NameResolving", &err);
- if (err)
- g_clear_error(&err);
- else
- btd_opts.name_resolv = boolean;
-
- boolean = g_key_file_get_boolean(config, "General",
- "DebugKeys", &err);
- if (err)
- g_clear_error(&err);
- else
- btd_opts.debug_keys = boolean;
-
- str = g_key_file_get_string(config, "General", "ControllerMode", &err);
- if (err) {
- g_clear_error(&err);
- } else {
- DBG("ControllerMode=%s", str);
- btd_opts.mode = get_mode(str);
- g_free(str);
- }
-
- val = g_key_file_get_integer(config, "General", "MaxControllers", &err);
- if (err) {
- g_clear_error(&err);
- } else {
- DBG("MaxControllers=%d", val);
- btd_opts.max_adapters = val;
- }
-
- str = g_key_file_get_string(config, "General", "MultiProfile", &err);
- if (err) {
- g_clear_error(&err);
- } else {
- DBG("MultiProfile=%s", str);
-
- if (!strcmp(str, "single"))
- btd_opts.mps = MPS_SINGLE;
- else if (!strcmp(str, "multiple"))
- btd_opts.mps = MPS_MULTIPLE;
- else
- btd_opts.mps = MPS_OFF;
-
- g_free(str);
- }
-
- boolean = g_key_file_get_boolean(config, "General",
- "FastConnectable", &err);
- if (err)
- g_clear_error(&err);
- else
- btd_opts.fast_conn = boolean;
-
- boolean = g_key_file_get_boolean(config, "General",
- "RefreshDiscovery", &err);
- if (err)
- g_clear_error(&err);
- else
- btd_opts.refresh_discovery = boolean;
-
- boolean = g_key_file_get_boolean(config, "General", "Experimental",
- &err);
- if (err)
- g_clear_error(&err);
- else
- btd_opts.experimental = boolean;
-
- strlist = g_key_file_get_string_list(config, "General",
- "KernelExperimental",
- NULL, &err);
- if (err)
- g_clear_error(&err);
- else {
- btd_parse_kernel_experimental(strlist);
- g_strfreev(strlist);
- }
-
- val = g_key_file_get_integer(config, "General",
- "RemoteNameRequestRetryDelay", &err);
- if (err) {
- DBG("%s", err->message);
- g_clear_error(&err);
- } else {
- DBG("RemoteNameRequestRetryDelay=%d", val);
- btd_opts.name_request_retry_delay = val;
- }
-
- str = g_key_file_get_string(config, "General",
- "SecureConnections", &err);
- if (err)
- g_clear_error(&err);
- else {
- if (!strcmp(str, "off"))
- btd_opts.secure_conn = SC_OFF;
- else if (!strcmp(str, "on"))
- btd_opts.secure_conn = SC_ON;
- else if (!strcmp(str, "only"))
- btd_opts.secure_conn = SC_ONLY;
- }
-
- str = g_key_file_get_string(config, "GATT", "Cache", &err);
- if (err) {
- DBG("%s", err->message);
- g_clear_error(&err);
- } else {
- btd_opts.gatt_cache = parse_gatt_cache(str);
- g_free(str);
- }
-
- val = g_key_file_get_integer(config, "GATT", "KeySize", &err);
- if (err) {
- DBG("%s", err->message);
- g_clear_error(&err);
- } else {
- DBG("KeySize=%d", val);
-
- if (val >=7 && val <= 16)
- btd_opts.key_size = val;
- }
-
- val = g_key_file_get_integer(config, "GATT", "ExchangeMTU", &err);
- if (err) {
- DBG("%s", err->message);
- g_clear_error(&err);
- } else {
- /* Ensure the mtu is within a valid range. */
- val = MIN(val, BT_ATT_MAX_LE_MTU);
- val = MAX(val, BT_ATT_DEFAULT_LE_MTU);
- DBG("ExchangeMTU=%d", val);
- btd_opts.gatt_mtu = val;
- }
-
- val = g_key_file_get_integer(config, "GATT", "Channels", &err);
- if (err) {
- DBG("%s", err->message);
- g_clear_error(&err);
- } else {
- DBG("Channels=%d", val);
- /* Ensure the channels is within a valid range. */
- val = MIN(val, 5);
- val = MAX(val, 1);
- btd_opts.gatt_channels = val;
- }
-
- str = g_key_file_get_string(config, "CSIS", "SIRK", &err);
- if (err) {
- DBG("%s", err->message);
- g_clear_error(&err);
- } else {
- DBG("CSIS SIRK: %s", str);
-
- if (strlen(str) == 32 && check_sirk_alpha_numeric(str)) {
- hex2bin(str, btd_opts.csis.sirk,
- sizeof(btd_opts.csis.sirk));
- } else if (!gen_sirk(str))
- DBG("Unable to generate SIRK from string");
-
- g_free(str);
- }
-
- boolean = g_key_file_get_boolean(config, "CSIS", "Encryption", &err);
- if (err) {
- DBG("%s", err->message);
- g_clear_error(&err);
- } else {
- DBG("CSIS Encryption: %s", boolean ? "true" : "false");
-
- btd_opts.csis.encrypt = boolean;
- }
-
- val = g_key_file_get_integer(config, "CSIS", "Size", &err);
- if (err) {
- DBG("%s", err->message);
- g_clear_error(&err);
- } else {
- val = MIN(val, 0xFF);
- val = MAX(val, 0);
- DBG("CSIS Size: %u", val);
- btd_opts.csis.size = val;
- }
-
- val = g_key_file_get_integer(config, "CSIS", "Rank", &err);
- if (err) {
- DBG("%s", err->message);
- g_clear_error(&err);
- } else {
- val = MIN(val, 0xFF);
- val = MAX(val, 0);
- DBG("CSIS Rank: %u", val);
- btd_opts.csis.rank = val;
- }
-
- str = g_key_file_get_string(config, "AVDTP", "SessionMode", &err);
- if (err) {
- DBG("%s", err->message);
- g_clear_error(&err);
- } else {
- DBG("SessionMode=%s", str);
-
- if (!strcmp(str, "basic"))
- btd_opts.avdtp.session_mode = BT_IO_MODE_BASIC;
- else if (!strcmp(str, "ertm"))
- btd_opts.avdtp.session_mode = BT_IO_MODE_ERTM;
- else {
- DBG("Invalid mode option: %s", str);
- btd_opts.avdtp.session_mode = BT_IO_MODE_BASIC;
- }
- g_free(str);
- }
-
- str = g_key_file_get_string(config, "AVDTP", "StreamMode", &err);
- if (err) {
- DBG("%s", err->message);
- g_clear_error(&err);
- } else {
- DBG("StreamMode=%s", str);
-
- if (!strcmp(str, "basic"))
- btd_opts.avdtp.stream_mode = BT_IO_MODE_BASIC;
- else if (!strcmp(str, "streaming"))
- btd_opts.avdtp.stream_mode = BT_IO_MODE_STREAMING;
- else {
- DBG("Invalid mode option: %s", str);
- btd_opts.avdtp.stream_mode = BT_IO_MODE_BASIC;
- }
- g_free(str);
- }
-
- val = g_key_file_get_integer(config, "AdvMon", "RSSISamplingPeriod",
- &err);
- if (err) {
- DBG("%s", err->message);
- g_clear_error(&err);
- } else {
- val = MIN(val, 0xFF);
- val = MAX(val, 0);
- DBG("RSSISamplingPeriod=%d", val);
- btd_opts.advmon.rssi_sampling_period = val;
- }
-
+ /* Parse Groups */
+ parse_general(config);
parse_br_config(config);
parse_le_config(config);
+ parse_gatt(config);
+ parse_csis(config);
+ parse_avdtp(config);
+ parse_advmon(config);
}
static void init_defaults(void)
@@ -1284,24 +1324,6 @@ static gboolean parse_debug(const char *key, const char *value,
return TRUE;
}
-static gboolean parse_kernel_experimental(const char *key, const char *value,
- gpointer user_data, GError **error)
-{
- char **strlist;
-
- if (value) {
- strlist = g_strsplit(value, ",", -1);
- btd_parse_kernel_experimental(strlist);
- g_strfreev(strlist);
- } else {
- if (!btd_opts.kernel)
- btd_opts.kernel = queue_new();
- queue_push_head(btd_opts.kernel, strdup("*"));
- }
-
- return TRUE;
-}
-
static GOptionEntry options[] = {
{ "debug", 'd', G_OPTION_FLAG_OPTIONAL_ARG,
G_OPTION_ARG_CALLBACK, parse_debug,
From: Luiz Augusto von Dentz <luiz.von.dentz@intel.com> This rework config option parsing adding helper function to make it simpler to parse new options. --- src/btd.h | 14 +- src/main.c | 848 +++++++++++++++++++++++++++-------------------------- 2 files changed, 442 insertions(+), 420 deletions(-)