2015-02-06 23:13:28

by Jakub Pawlowski

[permalink] [raw]
Subject: [PATCH BlueZ 1/4] core: adapter: Add StartFilteredDiscovery method

This patch introduces StartFilteredDiscovery method.
---
src/adapter.c | 9 +++++++++
1 file changed, 9 insertions(+)

diff --git a/src/adapter.c b/src/adapter.c
index 1839286..af6fafb 100644
--- a/src/adapter.c
+++ b/src/adapter.c
@@ -1744,6 +1744,12 @@ static DBusMessage *start_discovery(DBusConnection *conn,
return dbus_message_new_method_return(msg);
}

+static DBusMessage *start_filtered_discovery(DBusConnection *conn,
+ DBusMessage *msg, void *user_data)
+{
+ return btd_error_failed(msg, "Not implemented yet");
+}
+
static DBusMessage *stop_discovery(DBusConnection *conn,
DBusMessage *msg, void *user_data)
{
@@ -2278,6 +2284,9 @@ static DBusMessage *remove_device(DBusConnection *conn,

static const GDBusMethodTable adapter_methods[] = {
{ GDBUS_METHOD("StartDiscovery", NULL, NULL, start_discovery) },
+ { GDBUS_METHOD("StartFilteredDiscovery",
+ GDBUS_ARGS({ "properties", "a{sv}s" }), NULL,
+ start_filtered_discovery) },
{ GDBUS_METHOD("StopDiscovery", NULL, NULL, stop_discovery) },
{ GDBUS_ASYNC_METHOD("RemoveDevice",
GDBUS_ARGS({ "device", "o" }), NULL, remove_device) },
--
2.2.0.rc0.207.ga3a616c



2015-02-06 23:13:31

by Jakub Pawlowski

[permalink] [raw]
Subject: [PATCH BlueZ 4/4] core: adapter: Implement internals of StartFilteredDiscovery

This patch implement guts of StartFilteredDiscovery method. It adds new
structure, discovery_filter to client_watch that might contain
information about filter for given client.

It also adds discovery_method field to adapter, that's distinguishing
currently ruing discovery methods.
---
src/adapter.c | 293 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++--
1 file changed, 284 insertions(+), 9 deletions(-)

diff --git a/src/adapter.c b/src/adapter.c
index b7d9c77..424cdab 100644
--- a/src/adapter.c
+++ b/src/adapter.c
@@ -82,6 +82,7 @@
#define TEMP_DEV_TIMEOUT (3 * 60)
#define BONDING_TIMEOUT (2 * 60)

+#define HCI_RSSI_INVALID 127
#define DISTNACE_VAL_INVALID 0x7FFF

static DBusConnection *dbus_conn = NULL;
@@ -137,10 +138,18 @@ struct conn_param {
uint16_t timeout;
};

+struct discovery_filter {
+ uint8_t type;
+ uint16_t pathloss;
+ int16_t rssi;
+ GSList *uuids;
+};
+
struct watch_client {
struct btd_adapter *adapter;
char *owner;
guint watch;
+ struct discovery_filter *discovery_filter;
};

struct service_auth {
@@ -187,6 +196,7 @@ struct btd_adapter {

bool discovering; /* discovering property state */
uint8_t discovery_type; /* current active discovery type */
+ uint8_t discovery_method; /* current active discovery method */
uint8_t discovery_enable; /* discovery enabled/disabled */
bool discovery_suspended; /* discovery has been suspended */
GSList *discovery_list; /* list of discovery clients */
@@ -1342,6 +1352,7 @@ static void start_discovery_complete(uint8_t status, uint16_t length,
}

if (status == MGMT_STATUS_SUCCESS) {
+ adapter->discovery_method = MGMT_OP_START_DISCOVERY;
adapter->discovery_type = rp->type;
adapter->discovery_enable = 0x01;

@@ -1442,6 +1453,174 @@ static void trigger_start_discovery(struct btd_adapter *adapter, guint delay)
start_discovery_timeout, adapter);
}

+static void trigger_start_filtered_discovery(struct btd_adapter *adapter,
+ guint delay);
+
+static void start_filtered_discovery_complete(uint8_t status, uint16_t length,
+ const void *param, void *user_data)
+{
+ struct btd_adapter *adapter = user_data;
+ const int *type = param;
+
+ DBG("status 0x%02x", status);
+ if (length < 1) {
+ error("Wrong size of return parameters");
+ return;
+ }
+
+ if (status == MGMT_STATUS_SUCCESS) {
+ adapter->discovery_method = MGMT_OP_START_SERVICE_DISCOVERY;
+ adapter->discovery_enable = 0x01;
+ adapter->discovery_type = *type;
+
+ if (adapter->discovering)
+ return;
+
+ adapter->discovering = true;
+ g_dbus_emit_property_changed(dbus_conn, adapter->path,
+ ADAPTER_INTERFACE, "Discovering");
+ return;
+ }
+
+ /*
+ * In case the restart of the discovery failed, then just trigger
+ * it for the next idle timeout again.
+ */
+ trigger_start_filtered_discovery(adapter, IDLE_DISCOV_TIMEOUT * 2);
+}
+
+static struct mgmt_cp_start_service_discovery *discovery_filter_to_mgmt_cp(
+ struct btd_adapter *adapter)
+{
+ GSList *l, *m;
+ struct mgmt_cp_start_service_discovery *cp;
+ int rssi = DISTNACE_VAL_INVALID;
+ int uuid_count = 0;
+ uint8_t discovery_type = 0;
+ uint8_t (*current_uuid)[16];
+
+ for (l = adapter->discovery_list; l != NULL; l = g_slist_next(l)) {
+ struct watch_client *client = l->data;
+ struct discovery_filter *item = client->discovery_filter;
+
+ if (item == NULL) {
+ error("item == NULL this should never happen!!");
+ continue;
+ }
+
+ discovery_type += item->type;
+
+ if (item->rssi != DISTNACE_VAL_INVALID &&
+ rssi != HCI_RSSI_INVALID && rssi >= item->rssi)
+ rssi = item->rssi;
+ else if (item->pathloss != DISTNACE_VAL_INVALID)
+ /* if we're doing pathloss filtering, or no range
+ * filtering, we disable RSSI filter.
+ */
+ rssi = HCI_RSSI_INVALID;
+
+ uuid_count += g_slist_length(item->uuids);
+ }
+
+ /* if no proximity filtering is set, disable it */
+ if (rssi == DISTNACE_VAL_INVALID)
+ rssi = HCI_RSSI_INVALID;
+
+ cp = g_try_malloc(sizeof(cp) + 16*uuid_count);
+ if (cp == NULL)
+ return NULL;
+
+ cp->type = discovery_type;
+ cp->rssi = rssi;
+ cp->uuid_count = uuid_count;
+
+ current_uuid = cp->uuids;
+ for (l = adapter->discovery_list; l != NULL; l = g_slist_next(l)) {
+ struct watch_client *client = l->data;
+ struct discovery_filter *item = client->discovery_filter;
+
+ for (m = item->uuids; m != NULL; m = g_slist_next(m)) {
+ char *uuid_str = m->data;
+ uuid_t uuid_tmp;
+ uint128_t uint128;
+ uuid_t uuid128;
+
+ bt_string2uuid(&uuid_tmp, uuid_str);
+
+ uuid_to_uuid128(&uuid128, &uuid_tmp);
+ ntoh128((uint128_t *) uuid128.value.uuid128.data,
+ &uint128);
+ htob128(&uint128, (uint128_t *) current_uuid);
+
+ current_uuid++;
+ }
+ }
+ return cp;
+}
+
+static void free_discovery_filter(struct discovery_filter *discovery_filter)
+{
+ g_slist_free_full(discovery_filter->uuids, g_free);
+ g_free(discovery_filter);
+}
+
+static gboolean start_filtered_discovery_timeout(gpointer user_data)
+{
+ struct btd_adapter *adapter = user_data;
+ struct mgmt_cp_start_service_discovery *cp;
+
+ DBG("");
+
+ adapter->discovery_idle_timeout = 0;
+
+ /* if there's any scan running, stop it. */
+ if (adapter->discovery_enable == 0x01) {
+ struct mgmt_cp_stop_discovery cp;
+
+ cp.type = adapter->discovery_type;
+ mgmt_send(adapter->mgmt, MGMT_OP_STOP_DISCOVERY,
+ adapter->dev_id, sizeof(cp), &cp,
+ NULL, NULL, NULL);
+ }
+
+ cp = discovery_filter_to_mgmt_cp(adapter);
+ if (cp == NULL) {
+ error("discovery_filter_to_mgmt_cp returned NULL");
+ return FALSE;
+ }
+
+ mgmt_send(adapter->mgmt, MGMT_OP_START_SERVICE_DISCOVERY,
+ adapter->dev_id, sizeof(*cp) + cp->uuid_count * 16, cp,
+ start_filtered_discovery_complete, adapter, NULL);
+
+ g_free(cp);
+ return FALSE;
+}
+
+static void trigger_start_filtered_discovery(struct btd_adapter *adapter,
+ guint delay)
+{
+ DBG("");
+ cancel_passive_scanning(adapter);
+
+ if (adapter->discovery_idle_timeout > 0) {
+ g_source_remove(adapter->discovery_idle_timeout);
+ adapter->discovery_idle_timeout = 0;
+ }
+
+ /*
+ * If the controller got powered down in between, then ensure
+ * that we do not keep trying to restart discovery.
+ *
+ * This is safe-guard and should actually never trigger.
+ */
+ if (!(adapter->current_settings & MGMT_SETTING_POWERED))
+ return;
+
+ adapter->discovery_idle_timeout = g_timeout_add_seconds(delay,
+ start_filtered_discovery_timeout, adapter);
+}
+
static void suspend_discovery_complete(uint8_t status, uint16_t length,
const void *param, void *user_data)
{
@@ -1524,8 +1703,8 @@ static void discovering_callback(uint16_t index, uint16_t length,
return;
}

- DBG("hci%u type %u discovering %u", adapter->dev_id,
- ev->type, ev->discovering);
+ DBG("hci%u type %u discovering %u method %d", adapter->dev_id, ev->type,
+ ev->discovering, adapter->discovery_method);

if (adapter->discovery_enable == ev->discovering)
return;
@@ -1551,7 +1730,15 @@ static void discovering_callback(uint16_t index, uint16_t length,

switch (adapter->discovery_enable) {
case 0x00:
- trigger_start_discovery(adapter, IDLE_DISCOV_TIMEOUT);
+ if (adapter->discovery_method == MGMT_OP_START_DISCOVERY)
+ trigger_start_discovery(adapter, IDLE_DISCOV_TIMEOUT);
+ else if (adapter->discovery_method ==
+ MGMT_OP_START_SERVICE_DISCOVERY)
+ trigger_start_filtered_discovery(adapter, 0);
+ else
+ error("Wrong discovery_method: %d",
+ adapter->discovery_method);
+
break;

case 0x01:
@@ -1571,6 +1758,7 @@ static void stop_discovery_complete(uint8_t status, uint16_t length,
DBG("status 0x%02x", status);

if (status == MGMT_STATUS_SUCCESS) {
+ adapter->discovery_method = 0x00;
adapter->discovery_type = 0x00;
adapter->discovery_enable = 0x00;

@@ -1634,6 +1822,11 @@ static void discovery_destroy(void *user_data)
adapter->discovery_list = g_slist_remove(adapter->discovery_list,
client);

+ if (client->discovery_filter != NULL) {
+ free_discovery_filter(client->discovery_filter);
+ client->discovery_filter = NULL;
+ }
+
g_free(client->owner);
g_free(client);

@@ -1729,6 +1922,7 @@ static DBusMessage *start_discovery(DBusConnection *conn,

client->adapter = adapter;
client->owner = g_strdup(sender);
+ client->discovery_filter = NULL;
client->watch = g_dbus_add_disconnect_watch(dbus_conn, sender,
discovery_disconnect, client,
discovery_destroy);
@@ -1747,7 +1941,7 @@ static DBusMessage *start_discovery(DBusConnection *conn,
}

static bool parse_filtered_discovery_dict(char *key, DBusMessageIter *value,
- GSList *uuids, int16_t *rssi,
+ GSList **uuids, int16_t *rssi,
uint16_t *pathloss)
{
uint8_t type;
@@ -1774,7 +1968,7 @@ static bool parse_filtered_discovery_dict(char *key, DBusMessageIter *value,

result_uuid = bt_uuid2string(&uuid_tmp);

- uuids = g_slist_prepend(uuids, result_uuid);
+ *uuids = g_slist_prepend(*uuids, result_uuid);

dbus_message_iter_next(&arriter);
}
@@ -1802,7 +1996,9 @@ static DBusMessage *start_filtered_discovery(DBusConnection *conn,
DBusMessage *msg, void *user_data)
{
struct btd_adapter *adapter = user_data;
+ struct watch_client *client;
const char *sender = dbus_message_get_sender(msg);
+ struct discovery_filter *discovery_filter;
DBusMessageIter iter, subiter, dictiter, variantiter;
uint16_t pathloss = DISTNACE_VAL_INVALID;
int16_t rssi = DISTNACE_VAL_INVALID;
@@ -1855,7 +2051,7 @@ static DBusMessage *start_filtered_discovery(DBusConnection *conn,
dbus_message_iter_recurse(&dictiter, &variantiter);

if (!parse_filtered_discovery_dict(key, &variantiter,
- uuids, &rssi, &pathloss))
+ &uuids, &rssi, &pathloss))
goto invalid_args;
}

@@ -1886,8 +2082,37 @@ static DBusMessage *start_filtered_discovery(DBusConnection *conn,

DBG("filtered discovery params: type: %d rssi: %d pathloss: %d", type,
rssi, pathloss);
- g_slist_free_full(uuids, g_free);
- return btd_error_failed(msg, "Not implemented yet");
+
+ discovery_filter = g_try_malloc(sizeof(discovery_filter));
+ if (discovery_filter == NULL) {
+ g_slist_free_full(uuids, g_free);
+ return btd_error_failed(msg, "Not enough memory.");
+ }
+
+ discovery_filter->type = type;
+ discovery_filter->pathloss = pathloss;
+ discovery_filter->rssi = rssi;
+ discovery_filter->uuids = uuids;
+
+ client = g_new0(struct watch_client, 1);
+
+ client->adapter = adapter;
+ client->owner = g_strdup(sender);
+ client->discovery_filter = discovery_filter;
+ client->watch = g_dbus_add_disconnect_watch(dbus_conn, sender,
+ discovery_disconnect, client,
+ discovery_destroy);
+
+ adapter->discovery_list = g_slist_prepend(adapter->discovery_list,
+ client);
+ /*
+ * Just trigger the filtered discovery here. In case an already running
+ * discovery in idle phase exists, it will be restarted right
+ * away.
+ */
+ trigger_start_filtered_discovery(adapter, 0);
+
+ return dbus_message_new_method_return(msg);

invalid_args:
g_slist_free_full(uuids, g_free);
@@ -4829,6 +5054,46 @@ static void adapter_msd_notify(struct btd_adapter *adapter,
}
}

+static gint g_strcmp(gconstpointer a, gconstpointer b)
+{
+ return strcmp(a, b);
+}
+
+static bool is_filter_match(GSList *discovery_filter, struct eir_data *eir_data,
+ int8_t rssi)
+{
+ GSList *l, *m;
+ bool got_match = false;
+
+ for (l = discovery_filter; l != NULL && got_match != true;
+ l = g_slist_next(l)) {
+ struct watch_client *client = l->data;
+ struct discovery_filter *item = client->discovery_filter;
+
+ for (m = item->uuids; m != NULL && got_match != true;
+ m = g_slist_next(m))
+ /* m->data contains string representation of uuid. */
+ if (g_slist_find_custom(eir_data->services, m->data,
+ g_strcmp) != NULL)
+ got_match = true;
+
+ if (got_match) {
+ if (item->rssi != DISTNACE_VAL_INVALID &&
+ item->rssi > rssi)
+ return false;
+ if (item->pathloss != DISTNACE_VAL_INVALID &&
+ (eir_data->tx_power == 127 ||
+ eir_data->tx_power - rssi > item->pathloss))
+ return false;
+ }
+ }
+
+ if (!got_match)
+ return false;
+
+ return true;
+}
+
static void update_found_devices(struct btd_adapter *adapter,
const bdaddr_t *bdaddr,
uint8_t bdaddr_type, int8_t rssi,
@@ -4895,8 +5160,18 @@ static void update_found_devices(struct btd_adapter *adapter,
return;
}

+ if (adapter->discovery_method == MGMT_OP_START_SERVICE_DISCOVERY &&
+ !is_filter_match(adapter->discovery_list, &eir_data, rssi)) {
+ eir_data_free(&eir_data);
+ return;
+ }
+
device_set_legacy(dev, legacy);
- device_set_rssi(dev, rssi);
+
+ if (adapter->discovery_method == MGMT_OP_START_SERVICE_DISCOVERY)
+ device_set_rssi_no_delta(dev, rssi, false);
+ else
+ device_set_rssi(dev, rssi);

if (eir_data.appearance != 0)
device_set_appearance(dev, eir_data.appearance);
--
2.2.0.rc0.207.ga3a616c


2015-02-06 23:13:30

by Jakub Pawlowski

[permalink] [raw]
Subject: [PATCH BlueZ 3/4] core: device: add device_set_rssi_no_delta

This patch adds new method that allow to update RSSI value without
taking delta into account.
---
src/device.c | 10 ++++++++--
src/device.h | 2 ++
2 files changed, 10 insertions(+), 2 deletions(-)

diff --git a/src/device.c b/src/device.c
index a28d6fb..6c06c70 100644
--- a/src/device.c
+++ b/src/device.c
@@ -4417,7 +4417,8 @@ void device_set_legacy(struct btd_device *device, bool legacy)
DEVICE_INTERFACE, "LegacyPairing");
}

-void device_set_rssi(struct btd_device *device, int8_t rssi)
+void device_set_rssi_no_delta(struct btd_device *device, int8_t rssi,
+ bool use_delta)
{
if (!device)
return;
@@ -4438,7 +4439,7 @@ void device_set_rssi(struct btd_device *device, int8_t rssi)
delta = rssi - device->rssi;

/* only report changes of 8 dBm or more */
- if (delta < 8)
+ if (use_delta && delta < 8)
return;

DBG("rssi %d delta %d", rssi, delta);
@@ -4450,6 +4451,11 @@ void device_set_rssi(struct btd_device *device, int8_t rssi)
DEVICE_INTERFACE, "RSSI");
}

+void device_set_rssi(struct btd_device *device, int8_t rssi)
+{
+ device_set_rssi_no_delta(device, rssi, true);
+}
+
static gboolean start_discovery(gpointer user_data)
{
struct btd_device *device = user_data;
diff --git a/src/device.h b/src/device.h
index a7fefee..97e6f9e 100644
--- a/src/device.h
+++ b/src/device.h
@@ -89,6 +89,8 @@ void btd_device_set_temporary(struct btd_device *device, gboolean temporary);
void btd_device_set_trusted(struct btd_device *device, gboolean trusted);
void device_set_bonded(struct btd_device *device, uint8_t bdaddr_type);
void device_set_legacy(struct btd_device *device, bool legacy);
+void device_set_rssi_no_delta(struct btd_device *device, int8_t rssi,
+ bool use_delta);
void device_set_rssi(struct btd_device *device, int8_t rssi);
bool btd_device_is_connected(struct btd_device *dev);
uint8_t btd_device_get_bdaddr_type(struct btd_device *dev);
--
2.2.0.rc0.207.ga3a616c


2015-02-06 23:13:29

by Jakub Pawlowski

[permalink] [raw]
Subject: [PATCH BlueZ 2/4] core: adapter: Add parameter parsing to StartFilteredDiscovery

This patch adds parameter parsing and basic checks to
StartFilteredDiscovery method.
---
src/adapter.c | 144 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
1 file changed, 144 insertions(+)

diff --git a/src/adapter.c b/src/adapter.c
index af6fafb..b7d9c77 100644
--- a/src/adapter.c
+++ b/src/adapter.c
@@ -82,6 +82,8 @@
#define TEMP_DEV_TIMEOUT (3 * 60)
#define BONDING_TIMEOUT (2 * 60)

+#define DISTNACE_VAL_INVALID 0x7FFF
+
static DBusConnection *dbus_conn = NULL;

static bool kernel_conn_control = false;
@@ -1744,10 +1746,152 @@ static DBusMessage *start_discovery(DBusConnection *conn,
return dbus_message_new_method_return(msg);
}

+static bool parse_filtered_discovery_dict(char *key, DBusMessageIter *value,
+ GSList *uuids, int16_t *rssi,
+ uint16_t *pathloss)
+{
+ uint8_t type;
+
+ if (strcmp("UUIDS", key) == 0) {
+ DBusMessageIter arriter;
+
+ if (dbus_message_iter_get_arg_type(value) != DBUS_TYPE_ARRAY)
+ return false;
+ dbus_message_iter_recurse(value, &arriter);
+ while ((type = dbus_message_iter_get_arg_type(&arriter)) !=
+ DBUS_TYPE_INVALID) {
+ char *uuid_str;
+ char *result_uuid;
+ uuid_t uuid_tmp;
+
+ if (dbus_message_iter_get_arg_type(&arriter) !=
+ DBUS_TYPE_STRING)
+ return false;
+
+ dbus_message_iter_get_basic(&arriter, &uuid_str);
+ if (bt_string2uuid(&uuid_tmp, uuid_str) < 0)
+ return false;
+
+ result_uuid = bt_uuid2string(&uuid_tmp);
+
+ uuids = g_slist_prepend(uuids, result_uuid);
+
+ dbus_message_iter_next(&arriter);
+ }
+ } else if (strcmp("RSSI", key) == 0) {
+ if (dbus_message_iter_get_arg_type(value) != DBUS_TYPE_INT16)
+ return false;
+ dbus_message_iter_get_basic(value, rssi);
+ if (*rssi > 0 || *rssi < -127)
+ return false;
+ } else if (strcmp("pathloss", key) == 0) {
+ if (dbus_message_iter_get_arg_type(value) != DBUS_TYPE_UINT16)
+ return false;
+ dbus_message_iter_get_basic(value, pathloss);
+ if (*pathloss > 127)
+ return false;
+ } else {
+ DBG("Unknown key parameter: %s!\n", key);
+ return false;
+ }
+
+ return true;
+}
+
static DBusMessage *start_filtered_discovery(DBusConnection *conn,
DBusMessage *msg, void *user_data)
{
+ struct btd_adapter *adapter = user_data;
+ const char *sender = dbus_message_get_sender(msg);
+ DBusMessageIter iter, subiter, dictiter, variantiter;
+ uint16_t pathloss = DISTNACE_VAL_INVALID;
+ int16_t rssi = DISTNACE_VAL_INVALID;
+ GSList *uuids = NULL;
+ char *type_str;
+ uint8_t type;
+ GSList *list;
+
+ DBG("sender %s", sender);
+
+ if (!(adapter->current_settings & MGMT_SETTING_POWERED))
+ return btd_error_not_ready(msg);
+
+ /*
+ * Every client can only start one discovery, if the client
+ * already started a discovery then return an error.
+ */
+ list = g_slist_find_custom(adapter->discovery_list, sender,
+ compare_sender);
+ if (list)
+ return btd_error_busy(msg);
+
+ /* parse parameters */
+ dbus_message_iter_init(msg, &iter);
+
+ if (dbus_message_iter_get_arg_type(&iter) != DBUS_TYPE_ARRAY ||
+ dbus_message_iter_get_element_type(&iter) != DBUS_TYPE_DICT_ENTRY)
+ return btd_error_invalid_args(msg);
+
+ dbus_message_iter_recurse(&iter, &subiter);
+ do {
+ int type = dbus_message_iter_get_arg_type(&subiter);
+
+ if (type == DBUS_TYPE_INVALID)
+ break;
+
+ if (type == DBUS_TYPE_DICT_ENTRY) {
+ char *key;
+
+ dbus_message_iter_recurse(&subiter, &dictiter);
+
+ dbus_message_iter_get_basic(&dictiter, &key);
+ if (!dbus_message_iter_next(&dictiter))
+ return btd_error_invalid_args(msg);
+
+ if (dbus_message_iter_get_arg_type(&dictiter) !=
+ DBUS_TYPE_VARIANT)
+ return btd_error_invalid_args(msg);
+
+ dbus_message_iter_recurse(&dictiter, &variantiter);
+
+ if (!parse_filtered_discovery_dict(key, &variantiter,
+ uuids, &rssi, &pathloss))
+ goto invalid_args;
+ }
+
+ dbus_message_iter_next(&subiter);
+ } while (true);
+
+ if (!dbus_message_iter_next(&iter)) {
+ type = 7;
+ } else {
+ if (dbus_message_iter_get_arg_type(&iter) != DBUS_TYPE_STRING)
+ goto invalid_args;
+
+ dbus_message_iter_get_basic(&iter, &type_str);
+
+ if (strcmp(type_str, "bredr") == 0)
+ type = 1;
+ else if (strcmp(type_str, "le") == 0)
+ type = 6;
+ else if (strcmp(type_str, "auto") == 0)
+ type = 7;
+ else
+ goto invalid_args;
+ }
+
+ /* only pathlos or rssi can be set, never both*/
+ if (pathloss != DISTNACE_VAL_INVALID && rssi != DISTNACE_VAL_INVALID)
+ goto invalid_args;
+
+ DBG("filtered discovery params: type: %d rssi: %d pathloss: %d", type,
+ rssi, pathloss);
+ g_slist_free_full(uuids, g_free);
return btd_error_failed(msg, "Not implemented yet");
+
+invalid_args:
+ g_slist_free_full(uuids, g_free);
+ return btd_error_invalid_args(msg);
}

static DBusMessage *stop_discovery(DBusConnection *conn,
--
2.2.0.rc0.207.ga3a616c