client: Fix filtered scan
Empty list of UUIDs should be allowed to be passed to
set-scan-filter-uuids as bluetoothd accepts it to enable filtering
every UUID.
diff --git a/client/main.c b/client/main.c
index c75b558..9398a3e 100644
--- a/client/main.c
+++ b/client/main.c
@@ -932,6 +932,36 @@
dbus_message_iter_close_container(iter, &value);
}
+static void append_array_variant(DBusMessageIter *iter, int type, void *val,
+ int n_elements)
+{
+ DBusMessageIter variant, array;
+ char type_sig[2] = { type, '\0' };
+ char array_sig[3] = { DBUS_TYPE_ARRAY, type, '\0' };
+
+ dbus_message_iter_open_container(iter, DBUS_TYPE_VARIANT,
+ array_sig, &variant);
+
+ dbus_message_iter_open_container(&variant, DBUS_TYPE_ARRAY,
+ type_sig, &array);
+
+ if (dbus_type_is_fixed(type) == TRUE) {
+ dbus_message_iter_append_fixed_array(&array, type, val,
+ n_elements);
+ } else if (type == DBUS_TYPE_STRING || type == DBUS_TYPE_OBJECT_PATH) {
+ const char ***str_array = val;
+ int i;
+
+ for (i = 0; i < n_elements; i++)
+ dbus_message_iter_append_basic(&array, type,
+ &((*str_array)[i]));
+ }
+
+ dbus_message_iter_close_container(&variant, &array);
+
+ dbus_message_iter_close_container(iter, &variant);
+}
+
static void dict_append_entry(DBusMessageIter *dict, const char *key,
int type, void *val)
{
@@ -954,13 +984,37 @@
dbus_message_iter_close_container(dict, &entry);
}
+static void dict_append_basic_array(DBusMessageIter *dict, int key_type,
+ const void *key, int type, void *val,
+ int n_elements)
+{
+ DBusMessageIter entry;
+
+ dbus_message_iter_open_container(dict, DBUS_TYPE_DICT_ENTRY,
+ NULL, &entry);
+
+ dbus_message_iter_append_basic(&entry, key_type, key);
+
+ append_array_variant(&entry, type, val, n_elements);
+
+ dbus_message_iter_close_container(dict, &entry);
+}
+
+static void dict_append_array(DBusMessageIter *dict, const char *key, int type,
+ void *val, int n_elements)
+{
+ dict_append_basic_array(dict, DBUS_TYPE_STRING, &key, type, val,
+ n_elements);
+}
+
#define DISTANCE_VAL_INVALID 0x7FFF
struct set_discovery_filter_args {
char *transport;
dbus_uint16_t rssi;
dbus_int16_t pathloss;
- GSList *uuids;
+ char **uuids;
+ size_t uuids_len;
};
static void set_discovery_filter_setup(DBusMessageIter *iter, void *user_data)
@@ -974,37 +1028,8 @@
DBUS_TYPE_VARIANT_AS_STRING
DBUS_DICT_ENTRY_END_CHAR_AS_STRING, &dict);
- if (args->uuids != NULL) {
- DBusMessageIter entry, value, arrayIter;
- char *uuids = "UUIDs";
- GSList *l;
-
- dbus_message_iter_open_container(&dict, DBUS_TYPE_DICT_ENTRY,
- NULL, &entry);
- /* dict key */
- dbus_message_iter_append_basic(&entry, DBUS_TYPE_STRING,
- &uuids);
-
- dbus_message_iter_open_container(&entry, DBUS_TYPE_VARIANT,
- "as", &value);
-
- dbus_message_iter_open_container(&value, DBUS_TYPE_ARRAY, "s",
- &arrayIter);
-
- for (l = args->uuids; l != NULL; l = g_slist_next(l))
- /* list->data contains string representation of uuid */
- dbus_message_iter_append_basic(&arrayIter,
- DBUS_TYPE_STRING,
- &l->data);
-
- dbus_message_iter_close_container(&value, &arrayIter);
-
- /* close vararg*/
- dbus_message_iter_close_container(&entry, &value);
-
- /* close entry */
- dbus_message_iter_close_container(&dict, &entry);
- }
+ dict_append_array(&dict, "UUIDs", DBUS_TYPE_STRING, &args->uuids,
+ args->uuids_len);
if (args->pathloss != DISTANCE_VAL_INVALID)
dict_append_entry(&dict, "Pathloss", DBUS_TYPE_UINT16,
@@ -1037,7 +1062,8 @@
static gint filtered_scan_rssi = DISTANCE_VAL_INVALID;
static gint filtered_scan_pathloss = DISTANCE_VAL_INVALID;
-static GSList *filtered_scan_uuids;
+static char **filtered_scan_uuids;
+static size_t filtered_scan_uuids_len;
static char *filtered_scan_transport;
static void cmd_set_scan_filter_commit(void)
@@ -1049,6 +1075,7 @@
args.rssi = filtered_scan_rssi;
args.transport = filtered_scan_transport;
args.uuids = filtered_scan_uuids;
+ args.uuids_len = filtered_scan_uuids_len;
if (check_default_ctrl() == FALSE)
return;
@@ -1063,25 +1090,22 @@
static void cmd_set_scan_filter_uuids(const char *arg)
{
- char *uuid_str, *saveptr, *uuids, *uuidstmp;
-
- g_slist_free_full(filtered_scan_uuids, g_free);
+ g_strfreev(filtered_scan_uuids);
filtered_scan_uuids = NULL;
+ filtered_scan_uuids_len = 0;
if (!arg || !strlen(arg))
- return;
+ goto commit;
- uuids = g_strdup(arg);
- for (uuidstmp = uuids; ; uuidstmp = NULL) {
- uuid_str = strtok_r(uuidstmp, " \t", &saveptr);
- if (uuid_str == NULL)
- break;
- filtered_scan_uuids = g_slist_append(filtered_scan_uuids,
- strdup(uuid_str));
+ filtered_scan_uuids = g_strsplit(arg, " ", -1);
+ if (!filtered_scan_uuids) {
+ rl_printf("Failed to parse input\n");
+ return;
}
- g_free(uuids);
+ filtered_scan_uuids_len = g_strv_length(filtered_scan_uuids);
+commit:
cmd_set_scan_filter_commit();
}
@@ -1121,17 +1145,35 @@
cmd_set_scan_filter_commit();
}
+static void clear_discovery_filter_setup(DBusMessageIter *iter, void *user_data)
+{
+ DBusMessageIter dict;
+
+ dbus_message_iter_open_container(iter, DBUS_TYPE_ARRAY,
+ DBUS_DICT_ENTRY_BEGIN_CHAR_AS_STRING
+ DBUS_TYPE_STRING_AS_STRING
+ DBUS_TYPE_VARIANT_AS_STRING
+ DBUS_DICT_ENTRY_END_CHAR_AS_STRING, &dict);
+
+ dbus_message_iter_close_container(iter, &dict);
+}
+
static void cmd_set_scan_filter_clear(const char *arg)
{
/* set default values for all options */
filtered_scan_rssi = DISTANCE_VAL_INVALID;
filtered_scan_pathloss = DISTANCE_VAL_INVALID;
- g_slist_free_full(filtered_scan_uuids, g_free);
+ g_strfreev(filtered_scan_uuids);
filtered_scan_uuids = NULL;
+ filtered_scan_uuids_len = 0;
g_free(filtered_scan_transport);
filtered_scan_transport = NULL;
- cmd_set_scan_filter_commit();
+ if (g_dbus_proxy_method_call(default_ctrl, "SetDiscoveryFilter",
+ clear_discovery_filter_setup, set_discovery_filter_reply,
+ NULL, NULL) == FALSE) {
+ rl_printf("Failed to clear discovery filter\n");
+ }
}
static struct GDBusProxy *find_device(const char *arg)