Hi Arman, On Thu, Apr 23, 2015 at 11:21 PM, Arman Uguray <armansito@xxxxxxxxxxxx> wrote: > Hi, > >> On Wed, Apr 15, 2015 at 4:42 PM, Jakub Pawlowski <jpawlowski@xxxxxxxxxx> wrote: >> This patch adds set-scan-filter-* commands to sample DBus client that >> might be used to modify discovery filter. >> >> set-scan-filter-uuids - sets filter uuids field >> set-scan-filter-rssi - sets filter rssi and clears pathloss >> set-scan-filter-pathloss - sets filter pathloss and clears rssi >> set-scan-filter-transport - sets filter transport >> set-scan-filter-clear - clears filter >> --- >> client/main.c | 227 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ >> 1 file changed, 227 insertions(+) >> >> diff --git a/client/main.c b/client/main.c >> index bb67f3d..5b2d381 100644 >> --- a/client/main.c >> +++ b/client/main.c >> @@ -896,6 +896,222 @@ static void cmd_scan(const char *arg) >> } >> } >> >> +static void append_variant(DBusMessageIter *iter, int type, void *val) >> +{ >> + DBusMessageIter value; >> + char sig[2] = { type, '\0' }; >> + >> + dbus_message_iter_open_container(iter, DBUS_TYPE_VARIANT, sig, &value); >> + >> + dbus_message_iter_append_basic(&value, type, val); >> + >> + dbus_message_iter_close_container(iter, &value); >> +} >> + >> +static void dict_append_entry(DBusMessageIter *dict, const char *key, >> + int type, void *val) >> +{ >> + DBusMessageIter entry; >> + >> + if (type == DBUS_TYPE_STRING) { >> + const char *str = *((const char **) val); >> + >> + if (str == NULL) >> + return; >> + } >> + >> + dbus_message_iter_open_container(dict, DBUS_TYPE_DICT_ENTRY, >> + NULL, &entry); >> + >> + dbus_message_iter_append_basic(&entry, DBUS_TYPE_STRING, &key); >> + >> + append_variant(&entry, type, val); >> + >> + dbus_message_iter_close_container(dict, &entry); >> +} >> + >> +#define DISTANCE_VAL_INVALID 0x7FFF >> + >> +struct set_discovery_filter_args { >> + char *transport; >> + dbus_uint16_t rssi; >> + dbus_int16_t pathloss; >> + GSList *uuids; >> +}; >> + >> +static void set_discovery_filter_setup(DBusMessageIter *iter, >> + void *user_data) >> +{ >> + struct set_discovery_filter_args *args = 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); >> + >> + 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); >> + } >> + >> + if (args->pathloss != DISTANCE_VAL_INVALID) >> + dict_append_entry(&dict, "Pathloss", DBUS_TYPE_UINT16, >> + &args->pathloss); >> + >> + if (args->rssi != DISTANCE_VAL_INVALID) >> + dict_append_entry(&dict, "RSSI", DBUS_TYPE_INT16, &args->rssi); >> + >> + if (args->transport != NULL) >> + dict_append_entry(&dict, "Transport", DBUS_TYPE_STRING, >> + &args->transport); >> + >> + dbus_message_iter_close_container(iter, &dict); >> +} >> + >> + >> +static void set_discovery_filter_reply(DBusMessage *message, >> + void *user_data) >> +{ >> + DBusError error; >> + >> + dbus_error_init(&error); >> + if (dbus_set_error_from_message(&error, message) == TRUE) { >> + rl_printf("SetDiscoveryFilter failed: %s\n", error.name); >> + dbus_error_free(&error); >> + return; >> + } >> + >> + rl_printf("SetDiscoveryFilter success\n"); >> +} >> + >> +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_transport; >> + >> +static void cmd_set_scan_filter_commit(void) >> +{ >> + struct set_discovery_filter_args args; >> + >> + args.uuids = NULL; >> + args.pathloss = filtered_scan_pathloss; >> + args.rssi = filtered_scan_rssi; >> + args.transport = filtered_scan_transport; >> + args.uuids = filtered_scan_uuids; >> + >> + if (check_default_ctrl() == FALSE) >> + return; >> + >> + if (g_dbus_proxy_method_call(default_ctrl, "SetDiscoveryFilter", >> + set_discovery_filter_setup, set_discovery_filter_reply, >> + &args, NULL) == FALSE) { >> + rl_printf("Failed to set discovery filter\n"); >> + return; >> + } >> +} >> + >> +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); >> + filtered_scan_uuids = NULL; >> + >> + if (!arg || !strlen(arg)) >> + return; >> + >> + 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)); >> + } >> + >> + g_free(uuids); >> + >> + cmd_set_scan_filter_commit(); >> +} >> + >> +static void cmd_set_scan_filter_rssi(const char *arg) >> +{ >> + filtered_scan_pathloss = DISTANCE_VAL_INVALID; >> + >> + if (!arg || !strlen(arg)) >> + filtered_scan_rssi = DISTANCE_VAL_INVALID; >> + else >> + filtered_scan_rssi = atoi(arg); >> + >> + cmd_set_scan_filter_commit(); >> +} >> + >> +static void cmd_set_scan_filter_pathloss(const char *arg) >> +{ >> + filtered_scan_rssi = DISTANCE_VAL_INVALID; >> + >> + if (!arg || !strlen(arg)) >> + filtered_scan_pathloss = DISTANCE_VAL_INVALID; >> + else >> + filtered_scan_pathloss = atoi(arg); >> + >> + cmd_set_scan_filter_commit(); >> +} >> + >> +static void cmd_set_scan_filter_transport(const char *arg) >> +{ >> + g_free(filtered_scan_transport); >> + >> + if (!arg || !strlen(arg)) >> + filtered_scan_transport = NULL; >> + else >> + filtered_scan_transport = g_strdup(arg); >> + >> + cmd_set_scan_filter_commit(); >> +} >> + >> +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); >> + filtered_scan_uuids = NULL; >> + g_free(filtered_scan_transport); >> + filtered_scan_transport = NULL; >> + >> + cmd_set_scan_filter_commit(); >> +} >> + >> static struct GDBusProxy *find_device(const char *arg) >> { >> GDBusProxy *proxy; >> @@ -1468,6 +1684,17 @@ static const struct { >> capability_generator}, >> { "default-agent",NULL, cmd_default_agent, >> "Set agent as the default one" }, >> + { "set-scan-filter-uuids", "[uuid1 uuid2 ...]", >> + cmd_set_scan_filter_uuids, "Set scan filter uuids" }, >> + { "set-scan-filter-rssi", "[rssi]", cmd_set_scan_filter_rssi, >> + "Set scan filter rssi, and clears pathloss" }, >> + { "set-scan-filter-pathloss", "[pathloss]", >> + cmd_set_scan_filter_pathloss, >> + "Set scan filter pathloss, and clears rssi" }, >> + { "set-scan-filter-transport", "[transport]", >> + cmd_set_scan_filter_transport, "Set scan filter transport" }, >> + { "set-scan-filter-clear", "", cmd_set_scan_filter_clear, >> + "Clears discovery filter." }, >> { "scan", "<on/off>", cmd_scan, "Scan for devices" }, >> { "info", "[dev]", cmd_info, "Device information", >> dev_generator }, >> -- >> 2.2.0.rc0.207.ga3a616c >> >> -- >> To unsubscribe from this list: send the line "unsubscribe linux-bluetooth" in >> the body of a message to majordomo@xxxxxxxxxxxxxxx >> More majordomo info at http://vger.kernel.org/majordomo-info.html > > Luiz, any comments on this one? Is this good to go? This looks much better, I'd add the output of a test run just for the sake of completeness. -- Luiz Augusto von Dentz -- To unsubscribe from this list: send the line "unsubscribe linux-bluetooth" in the body of a message to majordomo@xxxxxxxxxxxxxxx More majordomo info at http://vger.kernel.org/majordomo-info.html