diff options
Diffstat (limited to 'wpa_supplicant/dbus/dbus_new_handlers_p2p.c')
-rw-r--r-- | wpa_supplicant/dbus/dbus_new_handlers_p2p.c | 939 |
1 files changed, 609 insertions, 330 deletions
diff --git a/wpa_supplicant/dbus/dbus_new_handlers_p2p.c b/wpa_supplicant/dbus/dbus_new_handlers_p2p.c index 30e0eb3e5fb8..0eff76386fa4 100644 --- a/wpa_supplicant/dbus/dbus_new_handlers_p2p.c +++ b/wpa_supplicant/dbus/dbus_new_handlers_p2p.c @@ -26,6 +26,7 @@ #include "ap/wps_hostapd.h" #include "../p2p_supplicant.h" +#include "../wifi_display.h" /** * Parses out the mac address from the peer object path. @@ -34,9 +35,9 @@ * @addr - out param must be of ETH_ALEN size * Returns 0 if valid (including MAC), -1 otherwise */ -static int parse_peer_object_path(char *peer_path, u8 addr[ETH_ALEN]) +static int parse_peer_object_path(const char *peer_path, u8 addr[ETH_ALEN]) { - char *p; + const char *p; if (!peer_path) return -1; @@ -56,12 +57,12 @@ static int parse_peer_object_path(char *peer_path, u8 addr[ETH_ALEN]) * * Convenience function to create and return an invalid persistent group error. */ -static DBusMessage * wpas_dbus_error_persistent_group_unknown( - DBusMessage *message) +static DBusMessage * +wpas_dbus_error_persistent_group_unknown(DBusMessage *message) { - return dbus_message_new_error(message, WPAS_DBUS_ERROR_NETWORK_UNKNOWN, - "There is no such persistent group in " - "this P2P device."); + return dbus_message_new_error( + message, WPAS_DBUS_ERROR_NETWORK_UNKNOWN, + "There is no such persistent group in this P2P device."); } @@ -73,7 +74,7 @@ DBusMessage * wpas_dbus_handler_p2p_find(DBusMessage *message, DBusMessageIter iter; DBusMessageIter iter_dict; unsigned int timeout = 0; - enum p2p_discovery_type type = P2P_FIND_ONLY_SOCIAL; + enum p2p_discovery_type type = P2P_FIND_START_WITH_FULL; int num_req_dev_types = 0; unsigned int i; u8 *req_dev_types = NULL; @@ -88,12 +89,12 @@ DBusMessage * wpas_dbus_handler_p2p_find(DBusMessage *message, if (!wpa_dbus_dict_get_entry(&iter_dict, &entry)) goto error; - if (!os_strcmp(entry.key, "Timeout") && - (entry.type == DBUS_TYPE_INT32)) { + if (os_strcmp(entry.key, "Timeout") == 0 && + entry.type == DBUS_TYPE_INT32) { timeout = entry.uint32_value; } else if (os_strcmp(entry.key, "RequestedDeviceTypes") == 0) { - if ((entry.type != DBUS_TYPE_ARRAY) || - (entry.array_type != WPAS_DBUS_TYPE_BINARRAY)) + if (entry.type != DBUS_TYPE_ARRAY || + entry.array_type != WPAS_DBUS_TYPE_BINARRAY) goto error_clear; os_free(req_dev_types); @@ -104,20 +105,20 @@ DBusMessage * wpas_dbus_handler_p2p_find(DBusMessage *message, for (i = 0; i < entry.array_len; i++) { if (wpabuf_len(entry.binarray_value[i]) != - WPS_DEV_TYPE_LEN) + WPS_DEV_TYPE_LEN) goto error_clear; os_memcpy(req_dev_types + i * WPS_DEV_TYPE_LEN, wpabuf_head(entry.binarray_value[i]), WPS_DEV_TYPE_LEN); } num_req_dev_types = entry.array_len; - } else if (!os_strcmp(entry.key, "DiscoveryType") && - (entry.type == DBUS_TYPE_STRING)) { - if (!os_strcmp(entry.str_value, "start_with_full")) + } else if (os_strcmp(entry.key, "DiscoveryType") == 0 && + entry.type == DBUS_TYPE_STRING) { + if (os_strcmp(entry.str_value, "start_with_full") == 0) type = P2P_FIND_START_WITH_FULL; - else if (!os_strcmp(entry.str_value, "social")) + else if (os_strcmp(entry.str_value, "social") == 0) type = P2P_FIND_ONLY_SOCIAL; - else if (!os_strcmp(entry.str_value, "progressive")) + else if (os_strcmp(entry.str_value, "progressive") == 0) type = P2P_FIND_PROGRESSIVE; else goto error_clear; @@ -126,8 +127,11 @@ DBusMessage * wpas_dbus_handler_p2p_find(DBusMessage *message, wpa_dbus_dict_entry_clear(&entry); } + if (wpa_s->p2p_dev) + wpa_s = wpa_s->p2p_dev; + wpas_p2p_find(wpa_s, timeout, type, num_req_dev_types, req_dev_types, - NULL, 0); + NULL, 0, 0, NULL, 0); os_free(req_dev_types); return reply; @@ -143,6 +147,9 @@ error: DBusMessage * wpas_dbus_handler_p2p_stop_find(DBusMessage *message, struct wpa_supplicant *wpa_s) { + if (wpa_s->p2p_dev) + wpa_s = wpa_s->p2p_dev; + wpas_p2p_stop_find(wpa_s); return NULL; } @@ -161,6 +168,9 @@ DBusMessage * wpas_dbus_handler_p2p_rejectpeer(DBusMessage *message, if (parse_peer_object_path(peer_object_path, peer_addr) < 0) return wpas_dbus_error_invalid_args(message, NULL); + if (wpa_s->p2p_dev) + wpa_s = wpa_s->p2p_dev; + if (wpas_p2p_reject(wpa_s, peer_addr) < 0) return wpas_dbus_error_unknown_error(message, "Failed to call wpas_p2p_reject method."); @@ -176,12 +186,16 @@ DBusMessage * wpas_dbus_handler_p2p_listen(DBusMessage *message, if (!dbus_message_get_args(message, NULL, DBUS_TYPE_INT32, &timeout, DBUS_TYPE_INVALID)) - return dbus_message_new_error(message, DBUS_ERROR_NO_MEMORY, - NULL); + return wpas_dbus_error_no_memory(message); + + if (wpa_s->p2p_dev) + wpa_s = wpa_s->p2p_dev; - if (wpas_p2p_listen(wpa_s, (unsigned int)timeout)) - return dbus_message_new_error(message, DBUS_ERROR_NO_MEMORY, - NULL); + if (wpas_p2p_listen(wpa_s, (unsigned int) timeout)) { + return dbus_message_new_error(message, + WPAS_DBUS_ERROR_UNKNOWN_ERROR, + "Could not start P2P listen"); + } return NULL; } @@ -205,17 +219,20 @@ DBusMessage * wpas_dbus_handler_p2p_extendedlisten( if (!wpa_dbus_dict_get_entry(&iter_dict, &entry)) goto error; - if (!os_strcmp(entry.key, "period") && - (entry.type == DBUS_TYPE_INT32)) + if (os_strcmp(entry.key, "period") == 0 && + entry.type == DBUS_TYPE_INT32) period = entry.uint32_value; - else if (!os_strcmp(entry.key, "interval") && - (entry.type == DBUS_TYPE_INT32)) + else if (os_strcmp(entry.key, "interval") == 0 && + entry.type == DBUS_TYPE_INT32) interval = entry.uint32_value; else goto error_clear; wpa_dbus_dict_entry_clear(&entry); } + if (wpa_s->p2p_dev) + wpa_s = wpa_s->p2p_dev; + if (wpas_p2p_ext_listen(wpa_s, period, interval)) return wpas_dbus_error_unknown_error( message, "failed to initiate a p2p_ext_listen."); @@ -247,16 +264,16 @@ DBusMessage * wpas_dbus_handler_p2p_presence_request( if (!wpa_dbus_dict_get_entry(&iter_dict, &entry)) goto error; - if (!os_strcmp(entry.key, "duration1") && - (entry.type == DBUS_TYPE_INT32)) + if (os_strcmp(entry.key, "duration1") == 0 && + entry.type == DBUS_TYPE_INT32) dur1 = entry.uint32_value; - else if (!os_strcmp(entry.key, "interval1") && + else if (os_strcmp(entry.key, "interval1") == 0 && entry.type == DBUS_TYPE_INT32) int1 = entry.uint32_value; - else if (!os_strcmp(entry.key, "duration2") && + else if (os_strcmp(entry.key, "duration2") == 0 && entry.type == DBUS_TYPE_INT32) dur2 = entry.uint32_value; - else if (!os_strcmp(entry.key, "interval2") && + else if (os_strcmp(entry.key, "interval2") == 0 && entry.type == DBUS_TYPE_INT32) int2 = entry.uint32_value; else @@ -264,6 +281,10 @@ DBusMessage * wpas_dbus_handler_p2p_presence_request( wpa_dbus_dict_entry_clear(&entry); } + + if (wpa_s->p2p_dev) + wpa_s = wpa_s->p2p_dev; + if (wpas_p2p_presence_req(wpa_s, dur1, int1, dur2, int2) < 0) return wpas_dbus_error_unknown_error(message, "Failed to invoke presence request."); @@ -288,7 +309,6 @@ DBusMessage * wpas_dbus_handler_p2p_group_add(DBusMessage *message, int persistent_group = 0; int freq = 0; char *iface = NULL; - char *net_id_str = NULL; unsigned int group_id = 0; struct wpa_ssid *ssid; @@ -301,15 +321,16 @@ DBusMessage * wpas_dbus_handler_p2p_group_add(DBusMessage *message, if (!wpa_dbus_dict_get_entry(&iter_dict, &entry)) goto inv_args; - if (!os_strcmp(entry.key, "persistent") && - (entry.type == DBUS_TYPE_BOOLEAN)) { - persistent_group = (entry.bool_value == TRUE) ? 1 : 0; - } else if (!os_strcmp(entry.key, "frequency") && - (entry.type == DBUS_TYPE_INT32)) { + if (os_strcmp(entry.key, "persistent") == 0 && + entry.type == DBUS_TYPE_BOOLEAN) { + persistent_group = entry.bool_value; + } else if (os_strcmp(entry.key, "frequency") == 0 && + entry.type == DBUS_TYPE_INT32) { freq = entry.int32_value; if (freq <= 0) goto inv_args_clear; - } else if (!os_strcmp(entry.key, "persistent_group_object") && + } else if (os_strcmp(entry.key, "persistent_group_object") == + 0 && entry.type == DBUS_TYPE_OBJECT_PATH) pg_object_path = os_strdup(entry.str_value); else @@ -318,15 +339,21 @@ DBusMessage * wpas_dbus_handler_p2p_group_add(DBusMessage *message, wpa_dbus_dict_entry_clear(&entry); } + if (wpa_s->p2p_dev) + wpa_s = wpa_s->p2p_dev; + if (pg_object_path != NULL) { + char *net_id_str; + /* * A persistent group Object Path is defined meaning we want * to re-invoke a persistent group. */ - iface = wpas_dbus_new_decompose_object_path(pg_object_path, 1, - &net_id_str, NULL); - if (iface == NULL || + iface = wpas_dbus_new_decompose_object_path( + pg_object_path, WPAS_DBUS_NEW_PERSISTENT_GROUPS_PART, + &net_id_str); + if (iface == NULL || net_id_str == NULL || os_strcmp(iface, wpa_s->dbus_new_path) != 0) { reply = wpas_dbus_error_invalid_args(message, @@ -346,18 +373,18 @@ DBusMessage * wpas_dbus_handler_p2p_group_add(DBusMessage *message, if (ssid == NULL || ssid->disabled != 2) goto inv_args; - if (wpas_p2p_group_add_persistent(wpa_s, ssid, 0, freq, 0)) { + if (wpas_p2p_group_add_persistent(wpa_s, ssid, 0, freq, 0, 0, 0, + NULL, 0)) { reply = wpas_dbus_error_unknown_error( message, "Failed to reinvoke a persistent group"); goto out; } - } else if (wpas_p2p_group_add(wpa_s, persistent_group, freq, 0)) + } else if (wpas_p2p_group_add(wpa_s, persistent_group, freq, 0, 0)) goto inv_args; out: os_free(pg_object_path); - os_free(net_id_str); os_free(iface); return reply; inv_args_clear: @@ -392,8 +419,7 @@ static dbus_bool_t wpa_dbus_p2p_check_enabled(struct wpa_supplicant *wpa_s, "P2P is not available for this interface"); } dbus_set_error_const(error, DBUS_ERROR_FAILED, - "P2P is not available for this " - "interface"); + "P2P is not available for this interface"); return FALSE; } return TRUE; @@ -408,6 +434,9 @@ DBusMessage * wpas_dbus_handler_p2p_flush(DBusMessage *message, if (!wpa_dbus_p2p_check_enabled(wpa_s, message, &reply, NULL)) return reply; + if (wpa_s->p2p_dev) + wpa_s = wpa_s->p2p_dev; + os_memset(wpa_s->p2p_auth_invite, 0, ETH_ALEN); wpa_s->force_long_sd = 0; p2p_flush(wpa_s->global->p2p); @@ -448,42 +477,42 @@ DBusMessage * wpas_dbus_handler_p2p_connect(DBusMessage *message, if (!wpa_dbus_dict_get_entry(&iter_dict, &entry)) goto inv_args; - if (!os_strcmp(entry.key, "peer") && - (entry.type == DBUS_TYPE_OBJECT_PATH)) { + if (os_strcmp(entry.key, "peer") == 0 && + entry.type == DBUS_TYPE_OBJECT_PATH) { peer_object_path = os_strdup(entry.str_value); - } else if (!os_strcmp(entry.key, "persistent") && - (entry.type == DBUS_TYPE_BOOLEAN)) { - persistent_group = (entry.bool_value == TRUE) ? 1 : 0; - } else if (!os_strcmp(entry.key, "join") && - (entry.type == DBUS_TYPE_BOOLEAN)) { - join = (entry.bool_value == TRUE) ? 1 : 0; - } else if (!os_strcmp(entry.key, "authorize_only") && - (entry.type == DBUS_TYPE_BOOLEAN)) { - authorize_only = (entry.bool_value == TRUE) ? 1 : 0; - } else if (!os_strcmp(entry.key, "frequency") && - (entry.type == DBUS_TYPE_INT32)) { + } else if (os_strcmp(entry.key, "persistent") == 0 && + entry.type == DBUS_TYPE_BOOLEAN) { + persistent_group = entry.bool_value; + } else if (os_strcmp(entry.key, "join") == 0 && + entry.type == DBUS_TYPE_BOOLEAN) { + join = entry.bool_value; + } else if (os_strcmp(entry.key, "authorize_only") == 0 && + entry.type == DBUS_TYPE_BOOLEAN) { + authorize_only = entry.bool_value; + } else if (os_strcmp(entry.key, "frequency") == 0 && + entry.type == DBUS_TYPE_INT32) { freq = entry.int32_value; if (freq <= 0) goto inv_args_clear; - } else if (!os_strcmp(entry.key, "go_intent") && - (entry.type == DBUS_TYPE_INT32)) { + } else if (os_strcmp(entry.key, "go_intent") == 0 && + entry.type == DBUS_TYPE_INT32) { go_intent = entry.int32_value; if ((go_intent < 0) || (go_intent > 15)) goto inv_args_clear; - } else if (!os_strcmp(entry.key, "wps_method") && - (entry.type == DBUS_TYPE_STRING)) { - if (!os_strcmp(entry.str_value, "pbc")) + } else if (os_strcmp(entry.key, "wps_method") == 0 && + entry.type == DBUS_TYPE_STRING) { + if (os_strcmp(entry.str_value, "pbc") == 0) wps_method = WPS_PBC; - else if (!os_strcmp(entry.str_value, "pin")) + else if (os_strcmp(entry.str_value, "pin") == 0) wps_method = WPS_PIN_DISPLAY; - else if (!os_strcmp(entry.str_value, "display")) + else if (os_strcmp(entry.str_value, "display") == 0) wps_method = WPS_PIN_DISPLAY; - else if (!os_strcmp(entry.str_value, "keypad")) + else if (os_strcmp(entry.str_value, "keypad") == 0) wps_method = WPS_PIN_KEYPAD; else goto inv_args_clear; - } else if (!os_strcmp(entry.key, "pin") && - (entry.type == DBUS_TYPE_STRING)) { + } else if (os_strcmp(entry.key, "pin") == 0 && + entry.type == DBUS_TYPE_STRING) { pin = os_strdup(entry.str_value); } else goto inv_args_clear; @@ -491,24 +520,28 @@ DBusMessage * wpas_dbus_handler_p2p_connect(DBusMessage *message, wpa_dbus_dict_entry_clear(&entry); } - if (!peer_object_path || (wps_method == WPS_NOT_READY) || - (parse_peer_object_path(peer_object_path, addr) < 0) || + if (wps_method == WPS_NOT_READY || + parse_peer_object_path(peer_object_path, addr) < 0 || !p2p_peer_known(wpa_s->global->p2p, addr)) goto inv_args; /* * Validate the wps_method specified and the pin value. */ - if ((!pin || !pin[0]) && (wps_method == WPS_PIN_KEYPAD)) + if ((!pin || !pin[0]) && wps_method == WPS_PIN_KEYPAD) goto inv_args; + if (wpa_s->p2p_dev) + wpa_s = wpa_s->p2p_dev; + new_pin = wpas_p2p_connect(wpa_s, addr, pin, wps_method, persistent_group, 0, join, authorize_only, - go_intent, freq, -1, 0, 0); + go_intent, freq, -1, 0, 0, 0); if (new_pin >= 0) { char npin[9]; char *generated_pin; + os_snprintf(npin, sizeof(npin), "%08d", new_pin); generated_pin = npin; reply = dbus_message_new_method_return(message); @@ -517,8 +550,8 @@ DBusMessage * wpas_dbus_handler_p2p_connect(DBusMessage *message, } else { switch (new_pin) { case -2: - err_msg = "connect failed due to channel " - "unavailability."; + err_msg = + "connect failed due to channel unavailability."; iface = WPAS_DBUS_ERROR_CONNECT_CHANNEL_UNAVAILABLE; break; @@ -564,7 +597,6 @@ DBusMessage * wpas_dbus_handler_p2p_invite(DBusMessage *message, char *peer_object_path = NULL; char *pg_object_path = NULL; char *iface = NULL; - char *net_id_str = NULL; u8 peer_addr[ETH_ALEN]; unsigned int group_id = 0; int persistent = 0; @@ -582,12 +614,13 @@ DBusMessage * wpas_dbus_handler_p2p_invite(DBusMessage *message, if (!wpa_dbus_dict_get_entry(&iter_dict, &entry)) goto err; - if (!os_strcmp(entry.key, "peer") && - (entry.type == DBUS_TYPE_OBJECT_PATH)) { + if (os_strcmp(entry.key, "peer") == 0 && + entry.type == DBUS_TYPE_OBJECT_PATH) { peer_object_path = os_strdup(entry.str_value); wpa_dbus_dict_entry_clear(&entry); - } else if (!os_strcmp(entry.key, "persistent_group_object") && - (entry.type == DBUS_TYPE_OBJECT_PATH)) { + } else if (os_strcmp(entry.key, "persistent_group_object") == + 0 && + entry.type == DBUS_TYPE_OBJECT_PATH) { pg_object_path = os_strdup(entry.str_value); persistent = 1; wpa_dbus_dict_entry_clear(&entry); @@ -597,21 +630,25 @@ DBusMessage * wpas_dbus_handler_p2p_invite(DBusMessage *message, } } - if (!peer_object_path || - (parse_peer_object_path(peer_object_path, peer_addr) < 0) || - !p2p_peer_known(wpa_s->global->p2p, peer_addr)) { + if (parse_peer_object_path(peer_object_path, peer_addr) < 0 || + !p2p_peer_known(wpa_s->global->p2p, peer_addr)) goto err; - } + + if (wpa_s->p2p_dev) + wpa_s = wpa_s->p2p_dev; if (persistent) { + char *net_id_str; /* * A group ID is defined meaning we want to re-invoke a * persistent group */ - iface = wpas_dbus_new_decompose_object_path(pg_object_path, 1, - &net_id_str, NULL); - if (iface == NULL || + iface = wpas_dbus_new_decompose_object_path( + pg_object_path, + WPAS_DBUS_NEW_PERSISTENT_GROUPS_PART, + &net_id_str); + if (iface == NULL || net_id_str == NULL || os_strcmp(iface, wpa_s->dbus_new_path) != 0) { reply = wpas_dbus_error_invalid_args(message, pg_object_path); @@ -630,7 +667,8 @@ DBusMessage * wpas_dbus_handler_p2p_invite(DBusMessage *message, if (ssid == NULL || ssid->disabled != 2) goto err; - if (wpas_p2p_invite(wpa_s, peer_addr, ssid, NULL, 0, 0) < 0) { + if (wpas_p2p_invite(wpa_s, peer_addr, ssid, NULL, 0, 0, 0, 0) < + 0) { reply = wpas_dbus_error_unknown_error( message, "Failed to reinvoke a persistent group"); @@ -649,6 +687,7 @@ DBusMessage * wpas_dbus_handler_p2p_invite(DBusMessage *message, } out: + os_free(iface); os_free(pg_object_path); os_free(peer_object_path); return reply; @@ -687,8 +726,11 @@ DBusMessage * wpas_dbus_handler_p2p_prov_disc_req(DBusMessage *message, os_strcmp(config_method, "pushbutton")) return wpas_dbus_error_invalid_args(message, NULL); + if (wpa_s->p2p_dev) + wpa_s = wpa_s->p2p_dev; + if (wpas_p2p_prov_disc(wpa_s, peer_addr, config_method, - WPAS_P2P_PD_FOR_GO_NEG) < 0) + WPAS_P2P_PD_FOR_GO_NEG, NULL) < 0) return wpas_dbus_error_unknown_error(message, "Failed to send provision discovery request"); @@ -716,6 +758,9 @@ dbus_bool_t wpas_dbus_getter_p2p_device_config(DBusMessageIter *iter, if (!wpa_dbus_p2p_check_enabled(wpa_s, NULL, NULL, error)) return FALSE; + if (wpa_s->p2p_dev) + wpa_s = wpa_s->p2p_dev; + if (!dbus_message_iter_open_container(iter, DBUS_TYPE_VARIANT, "a{sv}", &variant_iter) || !wpa_dbus_dict_open_write(&variant_iter, &dict_iter)) @@ -729,8 +774,8 @@ dbus_bool_t wpas_dbus_getter_p2p_device_config(DBusMessageIter *iter, /* Primary device type */ if (!wpa_dbus_dict_append_byte_array(&dict_iter, "PrimaryDeviceType", - (char *)wpa_s->conf->device_type, - WPS_DEV_TYPE_LEN)) + (char *) wpa_s->conf->device_type, + WPS_DEV_TYPE_LEN)) goto err_no_mem; /* Secondary device types */ @@ -765,65 +810,37 @@ dbus_bool_t wpas_dbus_getter_p2p_device_config(DBusMessageIter *iter, wpa_s->conf->wps_vendor_ext[i]; } - if (num_vendor_extensions && - !wpa_dbus_dict_append_wpabuf_array(&dict_iter, - "VendorExtension", - vendor_ext, - num_vendor_extensions)) - goto err_no_mem; - - /* GO Intent */ - if (!wpa_dbus_dict_append_uint32(&dict_iter, "GOIntent", - wpa_s->conf->p2p_go_intent)) - goto err_no_mem; - - /* Persistent Reconnect */ - if (!wpa_dbus_dict_append_bool(&dict_iter, "PersistentReconnect", - wpa_s->conf->persistent_reconnect)) - goto err_no_mem; - - /* Listen Reg Class */ - if (!wpa_dbus_dict_append_uint32(&dict_iter, "ListenRegClass", - wpa_s->conf->p2p_listen_reg_class)) - goto err_no_mem; - - /* Listen Channel */ - if (!wpa_dbus_dict_append_uint32(&dict_iter, "ListenChannel", - wpa_s->conf->p2p_listen_channel)) - goto err_no_mem; - - /* Oper Reg Class */ - if (!wpa_dbus_dict_append_uint32(&dict_iter, "OperRegClass", - wpa_s->conf->p2p_oper_reg_class)) - goto err_no_mem; - - /* Oper Channel */ - if (!wpa_dbus_dict_append_uint32(&dict_iter, "OperChannel", - wpa_s->conf->p2p_oper_channel)) - goto err_no_mem; - - /* SSID Postfix */ - if (wpa_s->conf->p2p_ssid_postfix && - !wpa_dbus_dict_append_string(&dict_iter, "SsidPostfix", - wpa_s->conf->p2p_ssid_postfix)) - goto err_no_mem; - - /* Intra Bss */ - if (!wpa_dbus_dict_append_bool(&dict_iter, "IntraBss", - wpa_s->conf->p2p_intra_bss)) - goto err_no_mem; - - /* Group Idle */ - if (!wpa_dbus_dict_append_uint32(&dict_iter, "GroupIdle", - wpa_s->conf->p2p_group_idle)) - goto err_no_mem; - - /* Dissasociation low ack */ - if (!wpa_dbus_dict_append_uint32(&dict_iter, "disassoc_low_ack", - wpa_s->conf->disassoc_low_ack)) - goto err_no_mem; - - if (!wpa_dbus_dict_close_write(&variant_iter, &dict_iter) || + if ((num_vendor_extensions && + !wpa_dbus_dict_append_wpabuf_array(&dict_iter, + "VendorExtension", + vendor_ext, + num_vendor_extensions)) || + !wpa_dbus_dict_append_uint32(&dict_iter, "GOIntent", + wpa_s->conf->p2p_go_intent) || + !wpa_dbus_dict_append_bool(&dict_iter, "PersistentReconnect", + wpa_s->conf->persistent_reconnect) || + !wpa_dbus_dict_append_uint32(&dict_iter, "ListenRegClass", + wpa_s->conf->p2p_listen_reg_class) || + !wpa_dbus_dict_append_uint32(&dict_iter, "ListenChannel", + wpa_s->conf->p2p_listen_channel) || + !wpa_dbus_dict_append_uint32(&dict_iter, "OperRegClass", + wpa_s->conf->p2p_oper_reg_class) || + !wpa_dbus_dict_append_uint32(&dict_iter, "OperChannel", + wpa_s->conf->p2p_oper_channel) || + (wpa_s->conf->p2p_ssid_postfix && + !wpa_dbus_dict_append_string(&dict_iter, "SsidPostfix", + wpa_s->conf->p2p_ssid_postfix)) || + !wpa_dbus_dict_append_bool(&dict_iter, "IntraBss", + wpa_s->conf->p2p_intra_bss) || + !wpa_dbus_dict_append_uint32(&dict_iter, "GroupIdle", + wpa_s->conf->p2p_group_idle) || + !wpa_dbus_dict_append_uint32(&dict_iter, "disassoc_low_ack", + wpa_s->conf->disassoc_low_ack) || + !wpa_dbus_dict_append_bool(&dict_iter, "NoGroupIface", + wpa_s->conf->p2p_no_group_iface) || + !wpa_dbus_dict_append_uint32(&dict_iter, "p2p_search_delay", + wpa_s->conf->p2p_search_delay) || + !wpa_dbus_dict_close_write(&variant_iter, &dict_iter) || !dbus_message_iter_close_container(iter, &variant_iter)) goto err_no_mem; @@ -847,6 +864,9 @@ dbus_bool_t wpas_dbus_setter_p2p_device_config(DBusMessageIter *iter, if (!wpa_dbus_p2p_check_enabled(wpa_s, NULL, NULL, error)) return FALSE; + if (wpa_s->p2p_dev) + wpa_s = wpa_s->p2p_dev; + dbus_message_iter_recurse(iter, &variant_iter); if (!wpa_dbus_dict_open_read(&variant_iter, &iter_dict, error)) return FALSE; @@ -902,8 +922,8 @@ dbus_bool_t wpas_dbus_setter_p2p_device_config(DBusMessageIter *iter, wpa_s->conf->changed_parameters |= CFG_CHANGED_SEC_DEVICE_TYPE; } else if (os_strcmp(entry.key, "VendorExtension") == 0) { - if ((entry.type != DBUS_TYPE_ARRAY) || - (entry.array_type != WPAS_DBUS_TYPE_BINARRAY) || + if (entry.type != DBUS_TYPE_ARRAY || + entry.array_type != WPAS_DBUS_TYPE_BINARRAY || (entry.array_len > P2P_MAX_WPS_VENDOR_EXT)) goto error; @@ -919,30 +939,30 @@ dbus_bool_t wpas_dbus_setter_p2p_device_config(DBusMessageIter *iter, } else wpa_s->conf->wps_vendor_ext[i] = NULL; } - } else if ((os_strcmp(entry.key, "GOIntent") == 0) && - (entry.type == DBUS_TYPE_UINT32) && + } else if (os_strcmp(entry.key, "GOIntent") == 0 && + entry.type == DBUS_TYPE_UINT32 && (entry.uint32_value <= 15)) wpa_s->conf->p2p_go_intent = entry.uint32_value; - else if ((os_strcmp(entry.key, "PersistentReconnect") == 0) && - (entry.type == DBUS_TYPE_BOOLEAN)) + else if (os_strcmp(entry.key, "PersistentReconnect") == 0 && + entry.type == DBUS_TYPE_BOOLEAN) wpa_s->conf->persistent_reconnect = entry.bool_value; - else if ((os_strcmp(entry.key, "ListenRegClass") == 0) && - (entry.type == DBUS_TYPE_UINT32)) { + else if (os_strcmp(entry.key, "ListenRegClass") == 0 && + entry.type == DBUS_TYPE_UINT32) { wpa_s->conf->p2p_listen_reg_class = entry.uint32_value; wpa_s->conf->changed_parameters |= CFG_CHANGED_P2P_LISTEN_CHANNEL; - } else if ((os_strcmp(entry.key, "ListenChannel") == 0) && - (entry.type == DBUS_TYPE_UINT32)) { + } else if (os_strcmp(entry.key, "ListenChannel") == 0 && + entry.type == DBUS_TYPE_UINT32) { wpa_s->conf->p2p_listen_channel = entry.uint32_value; wpa_s->conf->changed_parameters |= CFG_CHANGED_P2P_LISTEN_CHANNEL; - } else if ((os_strcmp(entry.key, "OperRegClass") == 0) && - (entry.type == DBUS_TYPE_UINT32)) { + } else if (os_strcmp(entry.key, "OperRegClass") == 0 && + entry.type == DBUS_TYPE_UINT32) { wpa_s->conf->p2p_oper_reg_class = entry.uint32_value; wpa_s->conf->changed_parameters |= CFG_CHANGED_P2P_OPER_CHANNEL; - } else if ((os_strcmp(entry.key, "OperChannel") == 0) && - (entry.type == DBUS_TYPE_UINT32)) { + } else if (os_strcmp(entry.key, "OperChannel") == 0 && + entry.type == DBUS_TYPE_UINT32) { wpa_s->conf->p2p_oper_channel = entry.uint32_value; wpa_s->conf->changed_parameters |= CFG_CHANGED_P2P_OPER_CHANNEL; @@ -961,17 +981,23 @@ dbus_bool_t wpas_dbus_setter_p2p_device_config(DBusMessageIter *iter, wpa_s->conf->changed_parameters |= CFG_CHANGED_P2P_SSID_POSTFIX; - } else if ((os_strcmp(entry.key, "IntraBss") == 0) && - (entry.type == DBUS_TYPE_BOOLEAN)) { + } else if (os_strcmp(entry.key, "IntraBss") == 0 && + entry.type == DBUS_TYPE_BOOLEAN) { wpa_s->conf->p2p_intra_bss = entry.bool_value; wpa_s->conf->changed_parameters |= CFG_CHANGED_P2P_INTRA_BSS; - } else if ((os_strcmp(entry.key, "GroupIdle") == 0) && - (entry.type == DBUS_TYPE_UINT32)) + } else if (os_strcmp(entry.key, "GroupIdle") == 0 && + entry.type == DBUS_TYPE_UINT32) wpa_s->conf->p2p_group_idle = entry.uint32_value; else if (os_strcmp(entry.key, "disassoc_low_ack") == 0 && entry.type == DBUS_TYPE_UINT32) wpa_s->conf->disassoc_low_ack = entry.uint32_value; + else if (os_strcmp(entry.key, "NoGroupIface") == 0 && + entry.type == DBUS_TYPE_BOOLEAN) + wpa_s->conf->p2p_no_group_iface = entry.bool_value; + else if (os_strcmp(entry.key, "p2p_search_delay") == 0 && + entry.type == DBUS_TYPE_UINT32) + wpa_s->conf->p2p_search_delay = entry.uint32_value; else goto error; @@ -1125,6 +1151,7 @@ dbus_bool_t wpas_dbus_getter_p2p_role(DBusMessageIter *iter, DBusError *error, break; default: str = "device"; + break; } return wpas_dbus_simple_property_getter(iter, DBUS_TYPE_STRING, &str, @@ -1240,8 +1267,8 @@ dbus_bool_t wpas_dbus_getter_p2p_peer_primary_device_type( dbus_bool_t wpas_dbus_getter_p2p_peer_config_method(DBusMessageIter *iter, - DBusError *error, - void *user_data) + DBusError *error, + void *user_data) { struct peer_handler_args *peer_args = user_data; const struct p2p_peer_info *info; @@ -1265,8 +1292,8 @@ dbus_bool_t wpas_dbus_getter_p2p_peer_config_method(DBusMessageIter *iter, dbus_bool_t wpas_dbus_getter_p2p_peer_level(DBusMessageIter *iter, - DBusError *error, - void *user_data) + DBusError *error, + void *user_data) { struct peer_handler_args *peer_args = user_data; const struct p2p_peer_info *info; @@ -1290,8 +1317,8 @@ dbus_bool_t wpas_dbus_getter_p2p_peer_level(DBusMessageIter *iter, dbus_bool_t wpas_dbus_getter_p2p_peer_device_capability(DBusMessageIter *iter, - DBusError *error, - void *user_data) + DBusError *error, + void *user_data) { struct peer_handler_args *peer_args = user_data; const struct p2p_peer_info *info; @@ -1349,8 +1376,7 @@ dbus_bool_t wpas_dbus_getter_p2p_peer_secondary_device_types( info = p2p_get_peer_found(peer_args->wpa_s->global->p2p, peer_args->p2p_device_addr, 0); if (info == NULL) { - dbus_set_error(error, DBUS_ERROR_FAILED, - "failed to find peer"); + dbus_set_error(error, DBUS_ERROR_FAILED, "failed to find peer"); return FALSE; } @@ -1358,18 +1384,13 @@ dbus_bool_t wpas_dbus_getter_p2p_peer_secondary_device_types( DBUS_TYPE_ARRAY_AS_STRING DBUS_TYPE_ARRAY_AS_STRING DBUS_TYPE_BYTE_AS_STRING, - &variant_iter)) { - dbus_set_error(error, DBUS_ERROR_FAILED, - "%s: failed to construct message 1", __func__); - return FALSE; - } - - if (!dbus_message_iter_open_container(&variant_iter, DBUS_TYPE_ARRAY, + &variant_iter) || + !dbus_message_iter_open_container(&variant_iter, DBUS_TYPE_ARRAY, DBUS_TYPE_ARRAY_AS_STRING DBUS_TYPE_BYTE_AS_STRING, &array_iter)) { dbus_set_error(error, DBUS_ERROR_FAILED, - "%s: failed to construct message 2", __func__); + "%s: failed to construct message 1", __func__); return FALSE; } @@ -1384,29 +1405,14 @@ dbus_bool_t wpas_dbus_getter_p2p_peer_secondary_device_types( if (!dbus_message_iter_open_container( &array_iter, DBUS_TYPE_ARRAY, DBUS_TYPE_BYTE_AS_STRING, - &inner_array_iter)) { - dbus_set_error(error, DBUS_ERROR_FAILED, - "%s: failed to construct " - "message 3 (%d)", - __func__, i); - return FALSE; - } - - if (!dbus_message_iter_append_fixed_array( + &inner_array_iter) || + !dbus_message_iter_append_fixed_array( &inner_array_iter, DBUS_TYPE_BYTE, - &sec_dev_type_list, WPS_DEV_TYPE_LEN)) { - dbus_set_error(error, DBUS_ERROR_FAILED, - "%s: failed to construct " - "message 4 (%d)", - __func__, i); - return FALSE; - } - - if (!dbus_message_iter_close_container( + &sec_dev_type_list, WPS_DEV_TYPE_LEN) || + !dbus_message_iter_close_container( &array_iter, &inner_array_iter)) { dbus_set_error(error, DBUS_ERROR_FAILED, - "%s: failed to construct " - "message 5 (%d)", + "%s: failed to construct message 2 (%d)", __func__, i); return FALSE; } @@ -1415,15 +1421,10 @@ dbus_bool_t wpas_dbus_getter_p2p_peer_secondary_device_types( } } - if (!dbus_message_iter_close_container(&variant_iter, &array_iter)) { + if (!dbus_message_iter_close_container(&variant_iter, &array_iter) || + !dbus_message_iter_close_container(iter, &variant_iter)) { dbus_set_error(error, DBUS_ERROR_FAILED, - "%s: failed to construct message 6", __func__); - return FALSE; - } - - if (!dbus_message_iter_close_container(iter, &variant_iter)) { - dbus_set_error(error, DBUS_ERROR_FAILED, - "%s: failed to construct message 7", __func__); + "%s: failed to construct message 3", __func__); return FALSE; } @@ -1436,7 +1437,7 @@ dbus_bool_t wpas_dbus_getter_p2p_peer_vendor_extension(DBusMessageIter *iter, void *user_data) { struct wpabuf *vendor_extension[P2P_MAX_WPS_VENDOR_EXT]; - int i, num; + unsigned int i, num = 0; struct peer_handler_args *peer_args = user_data; const struct p2p_peer_info *info; @@ -1449,7 +1450,8 @@ dbus_bool_t wpas_dbus_getter_p2p_peer_vendor_extension(DBusMessageIter *iter, } /* Add WPS vendor extensions attribute */ - for (i = 0, num = 0; i < P2P_MAX_WPS_VENDOR_EXT; i++) { + os_memset(vendor_extension, 0, sizeof(vendor_extension)); + for (i = 0; i < P2P_MAX_WPS_VENDOR_EXT; i++) { if (info->wps_vendor_ext[i] == NULL) continue; vendor_extension[num] = info->wps_vendor_ext[i]; @@ -1468,11 +1470,149 @@ dbus_bool_t wpas_dbus_getter_p2p_peer_vendor_extension(DBusMessageIter *iter, dbus_bool_t wpas_dbus_getter_p2p_peer_ies(DBusMessageIter *iter, DBusError *error, void *user_data) { - dbus_bool_t success; - /* struct peer_handler_args *peer_args = user_data; */ + struct peer_handler_args *peer_args = user_data; + const struct p2p_peer_info *info; + + info = p2p_get_peer_found(peer_args->wpa_s->global->p2p, + peer_args->p2p_device_addr, 0); + if (info == NULL) { + dbus_set_error(error, DBUS_ERROR_FAILED, + "failed to find peer"); + return FALSE; + } + + if (info->wfd_subelems == NULL) + return wpas_dbus_simple_array_property_getter(iter, + DBUS_TYPE_BYTE, + NULL, 0, error); + + return wpas_dbus_simple_array_property_getter( + iter, DBUS_TYPE_BYTE, (char *) info->wfd_subelems->buf, + info->wfd_subelems->used, error); +} + + +dbus_bool_t wpas_dbus_getter_p2p_peer_device_address(DBusMessageIter *iter, + DBusError *error, + void *user_data) +{ + struct peer_handler_args *peer_args = user_data; + const struct p2p_peer_info *info; + + info = p2p_get_peer_found(peer_args->wpa_s->global->p2p, + peer_args->p2p_device_addr, 0); + if (info == NULL) { + dbus_set_error(error, DBUS_ERROR_FAILED, + "failed to find peer"); + return FALSE; + } + + return wpas_dbus_simple_array_property_getter( + iter, DBUS_TYPE_BYTE, (char *) info->p2p_device_addr, + ETH_ALEN, error); +} + + +struct peer_group_data { + struct wpa_supplicant *wpa_s; + const struct p2p_peer_info *info; + char **paths; + unsigned int nb_paths; + int error; +}; + + +static int match_group_where_peer_is_client(struct p2p_group *group, + void *user_data) +{ + struct peer_group_data *data = user_data; + const struct p2p_group_config *cfg; + struct wpa_supplicant *wpa_s_go; + char **paths; + + if (!p2p_group_is_client_connected(group, data->info->p2p_device_addr)) + return 1; + + cfg = p2p_group_get_config(group); + + wpa_s_go = wpas_get_p2p_go_iface(data->wpa_s, cfg->ssid, + cfg->ssid_len); + if (wpa_s_go == NULL) + return 1; + + paths = os_realloc_array(data->paths, data->nb_paths + 1, + sizeof(char *)); + if (paths == NULL) + goto out_of_memory; + + data->paths = paths; + data->paths[data->nb_paths] = wpa_s_go->dbus_groupobj_path; + data->nb_paths++; + + return 1; + +out_of_memory: + data->error = ENOMEM; + return 0; +} + + +dbus_bool_t wpas_dbus_getter_p2p_peer_groups(DBusMessageIter *iter, + DBusError *error, + void *user_data) +{ + struct peer_handler_args *peer_args = user_data; + const struct p2p_peer_info *info; + struct peer_group_data data; + struct wpa_supplicant *wpa_s, *wpa_s_go; + dbus_bool_t success = FALSE; + + info = p2p_get_peer_found(peer_args->wpa_s->global->p2p, + peer_args->p2p_device_addr, 0); + if (info == NULL) { + dbus_set_error(error, DBUS_ERROR_FAILED, + "failed to find peer"); + return FALSE; + } + + os_memset(&data, 0, sizeof(data)); + + wpa_s = peer_args->wpa_s; + if (wpa_s->p2p_dev) + wpa_s = wpa_s->p2p_dev; + + wpa_s_go = wpas_get_p2p_client_iface(wpa_s, info->p2p_device_addr); + if (wpa_s_go) { + data.paths = os_calloc(1, sizeof(char *)); + if (data.paths == NULL) + goto out_of_memory; + data.paths[0] = wpa_s_go->dbus_groupobj_path; + data.nb_paths = 1; + } - success = wpas_dbus_simple_array_property_getter(iter, DBUS_TYPE_BYTE, - NULL, 0, error); + data.wpa_s = peer_args->wpa_s; + data.info = info; + + p2p_loop_on_all_groups(peer_args->wpa_s->global->p2p, + match_group_where_peer_is_client, &data); + if (data.error) + goto out_of_memory; + + if (data.paths == NULL) { + return wpas_dbus_simple_array_property_getter( + iter, DBUS_TYPE_OBJECT_PATH, NULL, 0, error); + } + + success = wpas_dbus_simple_array_property_getter(iter, + DBUS_TYPE_OBJECT_PATH, + data.paths, + data.nb_paths, error); + goto out; + +out_of_memory: + dbus_set_error_const(error, DBUS_ERROR_NO_MEMORY, "no memory"); +out: + os_free(data.paths); return success; } @@ -1496,15 +1636,6 @@ dbus_bool_t wpas_dbus_getter_persistent_groups(DBusMessageIter *iter, unsigned int i = 0, num = 0; dbus_bool_t success = FALSE; - if (wpa_s->conf == NULL) { - wpa_printf(MSG_ERROR, "dbus: %s: " - "An error occurred getting persistent groups list", - __func__); - dbus_set_error_const(error, DBUS_ERROR_FAILED, "an error " - "occurred getting persistent groups list"); - return FALSE; - } - for (ssid = wpa_s->conf->ssid; ssid; ssid = ssid->next) if (network_is_persistent_group(ssid)) num++; @@ -1617,12 +1748,12 @@ DBusMessage * wpas_dbus_handler_add_persistent_group( ssid = wpa_config_add_network(wpa_s->conf); if (ssid == NULL) { - wpa_printf(MSG_ERROR, "dbus: %s: " - "Cannot add new persistent group", __func__); + wpa_printf(MSG_ERROR, + "dbus: %s: Cannot add new persistent group", + __func__); reply = wpas_dbus_error_unknown_error( message, - "wpa_supplicant could not add " - "a persistent group on this interface."); + "wpa_supplicant could not add a persistent group on this interface."); goto err; } @@ -1635,13 +1766,12 @@ DBusMessage * wpas_dbus_handler_add_persistent_group( dbus_error_init(&error); if (!set_network_properties(wpa_s, ssid, &iter, &error)) { - wpa_printf(MSG_DEBUG, "dbus: %s: " - "Control interface could not set persistent group " - "properties", __func__); - reply = wpas_dbus_reply_new_from_error(message, &error, - DBUS_ERROR_INVALID_ARGS, - "Failed to set network " - "properties"); + wpa_printf(MSG_DEBUG, + "dbus: %s: Control interface could not set persistent group properties", + __func__); + reply = wpas_dbus_reply_new_from_error( + message, &error, DBUS_ERROR_INVALID_ARGS, + "Failed to set network properties"); dbus_error_free(&error); goto err; } @@ -1653,15 +1783,13 @@ DBusMessage * wpas_dbus_handler_add_persistent_group( reply = dbus_message_new_method_return(message); if (reply == NULL) { - reply = dbus_message_new_error(message, DBUS_ERROR_NO_MEMORY, - NULL); + reply = wpas_dbus_error_no_memory(message); goto err; } if (!dbus_message_append_args(reply, DBUS_TYPE_OBJECT_PATH, &path, DBUS_TYPE_INVALID)) { dbus_message_unref(reply); - reply = dbus_message_new_error(message, DBUS_ERROR_NO_MEMORY, - NULL); + reply = wpas_dbus_error_no_memory(message); goto err; } @@ -1691,7 +1819,7 @@ DBusMessage * wpas_dbus_handler_remove_persistent_group( { DBusMessage *reply = NULL; const char *op; - char *iface = NULL, *persistent_group_id = NULL; + char *iface = NULL, *persistent_group_id; int id; struct wpa_ssid *ssid; @@ -1702,10 +1830,11 @@ DBusMessage * wpas_dbus_handler_remove_persistent_group( * Extract the network ID and ensure the network is actually a child of * this interface. */ - iface = wpas_dbus_new_decompose_object_path(op, 1, - &persistent_group_id, - NULL); - if (iface == NULL || os_strcmp(iface, wpa_s->dbus_new_path) != 0) { + iface = wpas_dbus_new_decompose_object_path( + op, WPAS_DBUS_NEW_PERSISTENT_GROUPS_PART, + &persistent_group_id); + if (iface == NULL || persistent_group_id == NULL || + os_strcmp(iface, wpa_s->dbus_new_path) != 0) { reply = wpas_dbus_error_invalid_args(message, op); goto out; } @@ -1725,19 +1854,17 @@ DBusMessage * wpas_dbus_handler_remove_persistent_group( wpas_notify_persistent_group_removed(wpa_s, ssid); if (wpa_config_remove_network(wpa_s->conf, id) < 0) { - wpa_printf(MSG_ERROR, "dbus: %s: " - "error occurred when removing persistent group %d", + wpa_printf(MSG_ERROR, + "dbus: %s: error occurred when removing persistent group %d", __func__, id); reply = wpas_dbus_error_unknown_error( message, - "error removing the specified persistent group on " - "this interface."); + "error removing the specified persistent group on this interface."); goto out; } out: os_free(iface); - os_free(persistent_group_id); return reply; } @@ -1748,8 +1875,8 @@ static void remove_persistent_group(struct wpa_supplicant *wpa_s, wpas_notify_persistent_group_removed(wpa_s, ssid); if (wpa_config_remove_network(wpa_s->conf, ssid->id) < 0) { - wpa_printf(MSG_ERROR, "dbus: %s: " - "error occurred when removing persistent group %d", + wpa_printf(MSG_ERROR, + "dbus: %s: error occurred when removing persistent group %d", __func__, ssid->id); return; } @@ -1826,9 +1953,9 @@ dbus_bool_t wpas_dbus_getter_p2p_group_members(DBusMessageIter *iter, if (!paths[i]) goto out_of_memory; os_snprintf(paths[i], WPAS_DBUS_OBJECT_PATH_MAX, - "%s/" WPAS_DBUS_NEW_P2P_GROUPMEMBERS_PART + "%s/" WPAS_DBUS_NEW_P2P_PEERS_PART "/" COMPACT_MACSTR, - wpa_s->dbus_groupobj_path, MAC2STR(addr)); + wpa_s->parent->dbus_new_path, MAC2STR(addr)); i++; } @@ -1857,6 +1984,7 @@ dbus_bool_t wpas_dbus_getter_p2p_group_ssid(DBusMessageIter *iter, DBusError *error, void *user_data) { struct wpa_supplicant *wpa_s = user_data; + if (wpa_s->current_ssid == NULL) return FALSE; return wpas_dbus_simple_array_property_getter( @@ -1917,15 +2045,14 @@ dbus_bool_t wpas_dbus_getter_p2p_group_passphrase(DBusMessageIter *iter, void *user_data) { struct wpa_supplicant *wpa_s = user_data; - u8 role = wpas_get_p2p_role(wpa_s); - char *p_pass = NULL; + char *p_pass; + struct wpa_ssid *ssid = wpa_s->current_ssid; - /* Verify correct role for this property */ - if (role == WPAS_P2P_ROLE_GO) { - if (wpa_s->current_ssid == NULL) - return FALSE; - p_pass = wpa_s->current_ssid->passphrase; - } else + if (ssid == NULL) + return FALSE; + + p_pass = ssid->passphrase; + if (!p_pass) p_pass = ""; return wpas_dbus_simple_property_getter(iter, DBUS_TYPE_STRING, @@ -1938,20 +2065,20 @@ dbus_bool_t wpas_dbus_getter_p2p_group_psk(DBusMessageIter *iter, DBusError *error, void *user_data) { struct wpa_supplicant *wpa_s = user_data; - u8 role = wpas_get_p2p_role(wpa_s); u8 *p_psk = NULL; u8 psk_len = 0; + struct wpa_ssid *ssid = wpa_s->current_ssid; - /* Verify correct role for this property */ - if (role == WPAS_P2P_ROLE_CLIENT) { - if (wpa_s->current_ssid == NULL) - return FALSE; - p_psk = wpa_s->current_ssid->psk; - psk_len = 32; + if (ssid == NULL) + return FALSE; + + if (ssid->psk_set) { + p_psk = ssid->psk; + psk_len = sizeof(ssid->psk); } return wpas_dbus_simple_array_property_getter(iter, DBUS_TYPE_BYTE, - &p_psk, psk_len, error); + p_psk, psk_len, error); } @@ -1962,8 +2089,9 @@ dbus_bool_t wpas_dbus_getter_p2p_group_vendor_ext(DBusMessageIter *iter, struct wpa_supplicant *wpa_s = user_data; struct hostapd_data *hapd; struct wpabuf *vendor_ext[MAX_WPS_VENDOR_EXTENSIONS]; - int num_vendor_ext = 0; - int i; + unsigned int i, num_vendor_ext = 0; + + os_memset(vendor_ext, 0, sizeof(vendor_ext)); /* Verify correct role for this property */ if (wpas_get_p2p_role(wpa_s) == WPAS_P2P_ROLE_GO) { @@ -1974,11 +2102,9 @@ dbus_bool_t wpas_dbus_getter_p2p_group_vendor_ext(DBusMessageIter *iter, /* Parse WPS Vendor Extensions sent in Beacon/Probe Response */ for (i = 0; i < MAX_WPS_VENDOR_EXTENSIONS; i++) { if (hapd->conf->wps_vendor_ext[i] == NULL) - vendor_ext[i] = NULL; - else { - vendor_ext[num_vendor_ext++] = - hapd->conf->wps_vendor_ext[i]; - } + continue; + vendor_ext[num_vendor_ext++] = + hapd->conf->wps_vendor_ext[i]; } } @@ -1987,7 +2113,7 @@ dbus_bool_t wpas_dbus_getter_p2p_group_vendor_ext(DBusMessageIter *iter, DBUS_TYPE_BYTE, vendor_ext, num_vendor_ext, - error); + error); } @@ -1996,7 +2122,7 @@ dbus_bool_t wpas_dbus_setter_p2p_group_vendor_ext(DBusMessageIter *iter, void *user_data) { struct wpa_supplicant *wpa_s = user_data; - DBusMessageIter variant_iter, iter_dict; + DBusMessageIter variant_iter, iter_dict, array_iter, sub; struct wpa_dbus_dict_entry entry = { .type = DBUS_TYPE_STRING }; unsigned int i; struct hostapd_data *hapd = NULL; @@ -2008,6 +2134,82 @@ dbus_bool_t wpas_dbus_setter_p2p_group_vendor_ext(DBusMessageIter *iter, return FALSE; dbus_message_iter_recurse(iter, &variant_iter); + if (dbus_message_iter_get_arg_type(&variant_iter) != DBUS_TYPE_ARRAY) + return FALSE; + + /* + * This is supposed to be array of bytearrays (aay), but the earlier + * implementation used a dict with "WPSVendorExtensions" as the key in + * this setter function which does not match the format used by the + * getter function. For backwards compatibility, allow both formats to + * be used in the setter. + */ + if (dbus_message_iter_get_element_type(&variant_iter) == + DBUS_TYPE_ARRAY) { + /* This is the proper format matching the getter */ + struct wpabuf *vals[MAX_WPS_VENDOR_EXTENSIONS]; + + dbus_message_iter_recurse(&variant_iter, &array_iter); + + if (dbus_message_iter_get_arg_type(&array_iter) != + DBUS_TYPE_ARRAY || + dbus_message_iter_get_element_type(&array_iter) != + DBUS_TYPE_BYTE) { + wpa_printf(MSG_DEBUG, + "dbus: Not an array of array of bytes"); + return FALSE; + } + + i = 0; + os_memset(vals, 0, sizeof(vals)); + + while (dbus_message_iter_get_arg_type(&array_iter) == + DBUS_TYPE_ARRAY) { + char *val; + int len; + + if (i == MAX_WPS_VENDOR_EXTENSIONS) { + wpa_printf(MSG_DEBUG, + "dbus: Too many WPSVendorExtensions values"); + i = MAX_WPS_VENDOR_EXTENSIONS + 1; + break; + } + + dbus_message_iter_recurse(&array_iter, &sub); + dbus_message_iter_get_fixed_array(&sub, &val, &len); + wpa_hexdump(MSG_DEBUG, "dbus: WPSVendorExtentions[]", + val, len); + vals[i] = wpabuf_alloc_copy(val, len); + if (vals[i] == NULL) { + i = MAX_WPS_VENDOR_EXTENSIONS + 1; + break; + } + i++; + dbus_message_iter_next(&array_iter); + } + + if (i > MAX_WPS_VENDOR_EXTENSIONS) { + for (i = 0; i < MAX_WPS_VENDOR_EXTENSIONS; i++) + wpabuf_free(vals[i]); + return FALSE; + } + + for (i = 0; i < MAX_WPS_VENDOR_EXTENSIONS; i++) { + wpabuf_free(hapd->conf->wps_vendor_ext[i]); + hapd->conf->wps_vendor_ext[i] = vals[i]; + } + + hostapd_update_wps(hapd); + + return TRUE; + } + + if (dbus_message_iter_get_element_type(&variant_iter) != + DBUS_TYPE_DICT_ENTRY) + return FALSE; + + wpa_printf(MSG_DEBUG, + "dbus: Try to use backwards compatibility version of WPSVendorExtensions setter"); if (!wpa_dbus_dict_open_read(&variant_iter, &iter_dict, error)) return FALSE; @@ -2025,6 +2227,7 @@ dbus_bool_t wpas_dbus_setter_p2p_group_vendor_ext(DBusMessageIter *iter, goto error; for (i = 0; i < MAX_WPS_VENDOR_EXTENSIONS; i++) { + wpabuf_free(hapd->conf->wps_vendor_ext[i]); if (i < entry.array_len) { hapd->conf->wps_vendor_ext[i] = entry.binarray_value[i]; @@ -2073,30 +2276,31 @@ DBusMessage * wpas_dbus_handler_p2p_add_service(DBusMessage *message, if (!wpa_dbus_dict_get_entry(&iter_dict, &entry)) goto error; - if (!os_strcmp(entry.key, "service_type") && - (entry.type == DBUS_TYPE_STRING)) { - if (!os_strcmp(entry.str_value, "upnp")) + if (os_strcmp(entry.key, "service_type") == 0 && + entry.type == DBUS_TYPE_STRING) { + if (os_strcmp(entry.str_value, "upnp") == 0) upnp = 1; - else if (!os_strcmp(entry.str_value, "bonjour")) + else if (os_strcmp(entry.str_value, "bonjour") == 0) bonjour = 1; else goto error_clear; - } else if (!os_strcmp(entry.key, "version") && - entry.type == DBUS_TYPE_INT32) { + } else if (os_strcmp(entry.key, "version") == 0 && + entry.type == DBUS_TYPE_INT32) { version = entry.uint32_value; - } else if (!os_strcmp(entry.key, "service") && - (entry.type == DBUS_TYPE_STRING)) { + } else if (os_strcmp(entry.key, "service") == 0 && + entry.type == DBUS_TYPE_STRING) { + os_free(service); service = os_strdup(entry.str_value); - } else if (!os_strcmp(entry.key, "query")) { - if ((entry.type != DBUS_TYPE_ARRAY) || - (entry.array_type != DBUS_TYPE_BYTE)) + } else if (os_strcmp(entry.key, "query") == 0) { + if (entry.type != DBUS_TYPE_ARRAY || + entry.array_type != DBUS_TYPE_BYTE) goto error_clear; query = wpabuf_alloc_copy( entry.bytearray_value, entry.array_len); - } else if (!os_strcmp(entry.key, "response")) { - if ((entry.type != DBUS_TYPE_ARRAY) || - (entry.array_type != DBUS_TYPE_BYTE)) + } else if (os_strcmp(entry.key, "response") == 0) { + if (entry.type != DBUS_TYPE_ARRAY || + entry.array_type != DBUS_TYPE_BYTE) goto error_clear; resp = wpabuf_alloc_copy(entry.bytearray_value, entry.array_len); @@ -2111,8 +2315,6 @@ DBusMessage * wpas_dbus_handler_p2p_add_service(DBusMessage *message, if (wpas_p2p_service_add_upnp(wpa_s, version, service) != 0) goto error; - os_free(service); - service = NULL; } else if (bonjour == 1) { if (query == NULL || resp == NULL) goto error; @@ -2124,6 +2326,7 @@ DBusMessage * wpas_dbus_handler_p2p_add_service(DBusMessage *message, } else goto error; + os_free(service); return reply; error_clear: wpa_dbus_dict_entry_clear(&entry); @@ -2158,11 +2361,11 @@ DBusMessage * wpas_dbus_handler_p2p_delete_service( if (!wpa_dbus_dict_get_entry(&iter_dict, &entry)) goto error; - if (!os_strcmp(entry.key, "service_type") && - (entry.type == DBUS_TYPE_STRING)) { - if (!os_strcmp(entry.str_value, "upnp")) + if (os_strcmp(entry.key, "service_type") == 0 && + entry.type == DBUS_TYPE_STRING) { + if (os_strcmp(entry.str_value, "upnp") == 0) upnp = 1; - else if (!os_strcmp(entry.str_value, "bonjour")) + else if (os_strcmp(entry.str_value, "bonjour") == 0) bonjour = 1; else goto error_clear; @@ -2173,13 +2376,14 @@ DBusMessage * wpas_dbus_handler_p2p_delete_service( while (wpa_dbus_dict_has_dict_entry(&iter_dict)) { if (!wpa_dbus_dict_get_entry(&iter_dict, &entry)) goto error; - if (!os_strcmp(entry.key, "version") && + if (os_strcmp(entry.key, "version") == 0 && entry.type == DBUS_TYPE_INT32) version = entry.uint32_value; - else if (!os_strcmp(entry.key, "service") && - entry.type == DBUS_TYPE_STRING) + else if (os_strcmp(entry.key, "service") == 0 && + entry.type == DBUS_TYPE_STRING) { + os_free(service); service = os_strdup(entry.str_value); - else + } else goto error_clear; wpa_dbus_dict_entry_clear(&entry); @@ -2189,7 +2393,6 @@ DBusMessage * wpas_dbus_handler_p2p_delete_service( goto error; ret = wpas_p2p_service_del_upnp(wpa_s, version, service); - os_free(service); if (ret != 0) goto error; } else if (bonjour == 1) { @@ -2197,10 +2400,11 @@ DBusMessage * wpas_dbus_handler_p2p_delete_service( if (!wpa_dbus_dict_get_entry(&iter_dict, &entry)) goto error; - if (!os_strcmp(entry.key, "query")) { - if ((entry.type != DBUS_TYPE_ARRAY) || - (entry.array_type != DBUS_TYPE_BYTE)) + if (os_strcmp(entry.key, "query") == 0) { + if (entry.type != DBUS_TYPE_ARRAY || + entry.array_type != DBUS_TYPE_BYTE) goto error_clear; + wpabuf_free(query); query = wpabuf_alloc_copy( entry.bytearray_value, entry.array_len); @@ -2216,14 +2420,17 @@ DBusMessage * wpas_dbus_handler_p2p_delete_service( ret = wpas_p2p_service_del_bonjour(wpa_s, query); if (ret != 0) goto error; - wpabuf_free(query); } else goto error; + wpabuf_free(query); + os_free(service); return reply; error_clear: wpa_dbus_dict_entry_clear(&entry); error: + wpabuf_free(query); + os_free(service); return wpas_dbus_error_invalid_args(message, NULL); } @@ -2259,22 +2466,22 @@ DBusMessage * wpas_dbus_handler_p2p_service_sd_req( while (wpa_dbus_dict_has_dict_entry(&iter_dict)) { if (!wpa_dbus_dict_get_entry(&iter_dict, &entry)) goto error; - if (!os_strcmp(entry.key, "peer_object") && + if (os_strcmp(entry.key, "peer_object") == 0 && entry.type == DBUS_TYPE_OBJECT_PATH) { peer_object_path = os_strdup(entry.str_value); - } else if (!os_strcmp(entry.key, "service_type") && + } else if (os_strcmp(entry.key, "service_type") == 0 && entry.type == DBUS_TYPE_STRING) { - if (!os_strcmp(entry.str_value, "upnp")) + if (os_strcmp(entry.str_value, "upnp") == 0) upnp = 1; else goto error_clear; - } else if (!os_strcmp(entry.key, "version") && + } else if (os_strcmp(entry.key, "version") == 0 && entry.type == DBUS_TYPE_INT32) { version = entry.uint32_value; - } else if (!os_strcmp(entry.key, "service") && + } else if (os_strcmp(entry.key, "service") == 0 && entry.type == DBUS_TYPE_STRING) { service = os_strdup(entry.str_value); - } else if (!os_strcmp(entry.key, "tlv")) { + } else if (os_strcmp(entry.key, "tlv") == 0) { if (entry.type != DBUS_TYPE_ARRAY || entry.array_type != DBUS_TYPE_BYTE) goto error_clear; @@ -2352,16 +2559,17 @@ DBusMessage * wpas_dbus_handler_p2p_service_sd_res( if (!wpa_dbus_dict_get_entry(&iter_dict, &entry)) goto error; - if (!os_strcmp(entry.key, "peer_object") && + if (os_strcmp(entry.key, "peer_object") == 0 && entry.type == DBUS_TYPE_OBJECT_PATH) { peer_object_path = os_strdup(entry.str_value); - } else if (!os_strcmp(entry.key, "frequency") && + } else if (os_strcmp(entry.key, "frequency") == 0 && entry.type == DBUS_TYPE_INT32) { freq = entry.uint32_value; - } else if (!os_strcmp(entry.key, "dialog_token") && - entry.type == DBUS_TYPE_UINT32) { + } else if (os_strcmp(entry.key, "dialog_token") == 0 && + (entry.type == DBUS_TYPE_UINT32 || + entry.type == DBUS_TYPE_INT32)) { dlg_tok = entry.uint32_value; - } else if (!os_strcmp(entry.key, "tlvs")) { + } else if (os_strcmp(entry.key, "tlvs") == 0) { if (entry.type != DBUS_TYPE_ARRAY || entry.array_type != DBUS_TYPE_BYTE) goto error_clear; @@ -2372,12 +2580,9 @@ DBusMessage * wpas_dbus_handler_p2p_service_sd_res( wpa_dbus_dict_entry_clear(&entry); } - if (!peer_object_path || - (parse_peer_object_path(peer_object_path, addr) < 0) || - !p2p_peer_known(wpa_s->global->p2p, addr)) - goto error; - - if (tlv == NULL) + if (parse_peer_object_path(peer_object_path, addr) < 0 || + !p2p_peer_known(wpa_s->global->p2p, addr) || + tlv == NULL) goto error; wpas_p2p_sd_response(wpa_s, freq, addr, (u8) dlg_tok, tlv); @@ -2405,7 +2610,7 @@ DBusMessage * wpas_dbus_handler_p2p_service_sd_cancel_req( if (req == 0) goto error; - if (!wpas_p2p_sd_cancel_request(wpa_s, req)) + if (wpas_p2p_sd_cancel_request(wpa_s, req) < 0) goto error; return NULL; @@ -2436,3 +2641,77 @@ DBusMessage * wpas_dbus_handler_p2p_serv_disc_external( return NULL; } + + +#ifdef CONFIG_WIFI_DISPLAY + +dbus_bool_t wpas_dbus_getter_global_wfd_ies(DBusMessageIter *iter, + DBusError *error, void *user_data) +{ + struct wpa_global *global = user_data; + struct wpabuf *ie; + dbus_bool_t ret; + + ie = wifi_display_get_wfd_ie(global); + if (ie == NULL) + return wpas_dbus_simple_array_property_getter(iter, + DBUS_TYPE_BYTE, + NULL, 0, error); + + ret = wpas_dbus_simple_array_property_getter(iter, DBUS_TYPE_BYTE, + wpabuf_head(ie), + wpabuf_len(ie), error); + wpabuf_free(ie); + + return ret; +} + + +dbus_bool_t wpas_dbus_setter_global_wfd_ies(DBusMessageIter *iter, + DBusError *error, void *user_data) +{ + struct wpa_global *global = user_data; + DBusMessageIter variant, array; + struct wpabuf *ie = NULL; + const u8 *data; + int len; + + if (dbus_message_iter_get_arg_type(iter) != DBUS_TYPE_VARIANT) + goto err; + + dbus_message_iter_recurse(iter, &variant); + if (dbus_message_iter_get_arg_type(&variant) != DBUS_TYPE_ARRAY) + goto err; + + dbus_message_iter_recurse(&variant, &array); + dbus_message_iter_get_fixed_array(&array, &data, &len); + if (len == 0) { + wifi_display_enable(global, 0); + wifi_display_deinit(global); + + return TRUE; + } + + ie = wpabuf_alloc(len); + if (ie == NULL) + goto err; + + wpabuf_put_data(ie, data, len); + if (wifi_display_subelem_set_from_ies(global, ie) != 0) + goto err; + + if (global->wifi_display == 0) + wifi_display_enable(global, 1); + + wpabuf_free(ie); + + return TRUE; +err: + wpabuf_free(ie); + + dbus_set_error_const(error, DBUS_ERROR_INVALID_ARGS, + "invalid message format"); + return FALSE; +} + +#endif /* CONFIG_WIFI_DISPLAY */ |