]> git.ipfire.org Git - thirdparty/hostap.git/blobdiff - wpa_supplicant/dbus/dbus_new_handlers_p2p.c
P2P: Allow p2p_invite-persistent to specify channel for GO
[thirdparty/hostap.git] / wpa_supplicant / dbus / dbus_new_handlers_p2p.c
index ad3cc113706a15d892e19e27cace9917efb25fd7..30e0eb3e5fb8c7f215057c59329168f1ec324aa7 100644 (file)
@@ -1,14 +1,9 @@
 /*
  * WPA Supplicant / dbus-based control interface (P2P)
+ * Copyright (c) 2011-2012, Intel Corporation
  *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
- *
- * Alternatively, this software may be distributed under the terms of BSD
- * license.
- *
- * See README and COPYING for more details.
+ * This software may be distributed under the terms of the BSD license.
+ * See README for more details.
  */
 
 #include "includes.h"
@@ -132,7 +127,7 @@ DBusMessage * wpas_dbus_handler_p2p_find(DBusMessage *message,
        }
 
        wpas_p2p_find(wpa_s, timeout, type, num_req_dev_types, req_dev_types,
-                     NULL);
+                     NULL, 0);
        os_free(req_dev_types);
        return reply;
 
@@ -351,13 +346,13 @@ 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)) {
+               if (wpas_p2p_group_add_persistent(wpa_s, ssid, 0, freq, 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))
+       } else if (wpas_p2p_group_add(wpa_s, persistent_group, freq, 0))
                goto inv_args;
 
 out:
@@ -509,7 +504,7 @@ DBusMessage * wpas_dbus_handler_p2p_connect(DBusMessage *message,
 
        new_pin = wpas_p2p_connect(wpa_s, addr, pin, wps_method,
                                   persistent_group, 0, join, authorize_only,
-                                  go_intent, freq);
+                                  go_intent, freq, -1, 0, 0);
 
        if (new_pin >= 0) {
                char npin[9];
@@ -635,7 +630,7 @@ 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) {
+               if (wpas_p2p_invite(wpa_s, peer_addr, ssid, NULL, 0, 0) < 0) {
                        reply = wpas_dbus_error_unknown_error(
                                message,
                                "Failed to reinvoke a persistent group");
@@ -692,7 +687,8 @@ DBusMessage * wpas_dbus_handler_p2p_prov_disc_req(DBusMessage *message,
            os_strcmp(config_method, "pushbutton"))
                return wpas_dbus_error_invalid_args(message, NULL);
 
-       if (wpas_p2p_prov_disc(wpa_s, peer_addr, config_method, 0) < 0)
+       if (wpas_p2p_prov_disc(wpa_s, peer_addr, config_method,
+                              WPAS_P2P_PD_FOR_GO_NEG) < 0)
                return wpas_dbus_error_unknown_error(message,
                                "Failed to send provision discovery request");
 
@@ -704,9 +700,9 @@ DBusMessage * wpas_dbus_handler_p2p_prov_disc_req(DBusMessage *message,
  * P2P Device property accessor methods.
  */
 
-dbus_bool_t wpas_dbus_getter_p2p_device_properties(DBusMessageIter *iter,
-                                                  DBusError *error,
-                                                  void *user_data)
+dbus_bool_t wpas_dbus_getter_p2p_device_config(DBusMessageIter *iter,
+                                              DBusError *error,
+                                              void *user_data)
 {
        struct wpa_supplicant *wpa_s = user_data;
        DBusMessageIter variant_iter, dict_iter;
@@ -782,7 +778,7 @@ dbus_bool_t wpas_dbus_getter_p2p_device_properties(DBusMessageIter *iter,
                goto err_no_mem;
 
        /* Persistent Reconnect */
-       if (!wpa_dbus_dict_append_bool(&dict_iter, "PersistantReconnect",
+       if (!wpa_dbus_dict_append_bool(&dict_iter, "PersistentReconnect",
                                       wpa_s->conf->persistent_reconnect))
                goto err_no_mem;
 
@@ -839,9 +835,9 @@ err_no_mem:
 }
 
 
-dbus_bool_t wpas_dbus_setter_p2p_device_properties(DBusMessageIter *iter,
-                                                  DBusError *error,
-                                                  void *user_data)
+dbus_bool_t wpas_dbus_setter_p2p_device_config(DBusMessageIter *iter,
+                                              DBusError *error,
+                                              void *user_data)
 {
        struct wpa_supplicant *wpa_s = user_data;
        DBusMessageIter variant_iter, iter_dict;
@@ -927,7 +923,7 @@ dbus_bool_t wpas_dbus_setter_p2p_device_properties(DBusMessageIter *iter,
                           (entry.type == DBUS_TYPE_UINT32) &&
                           (entry.uint32_value <= 15))
                        wpa_s->conf->p2p_go_intent = entry.uint32_value;
-               else if ((os_strcmp(entry.key, "PersistantReconnect") == 0) &&
+               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) &&
@@ -1053,7 +1049,7 @@ dbus_bool_t wpas_dbus_getter_p2p_peers(DBusMessageIter *iter, DBusError *error,
         * Now construct the peer object paths in a form suitable for
         * array_property_getter helper below.
         */
-       peer_obj_paths = os_zalloc(num * sizeof(char *));
+       peer_obj_paths = os_calloc(num, sizeof(char *));
 
        if (!peer_obj_paths) {
                out_of_mem = 1;
@@ -1140,13 +1136,18 @@ dbus_bool_t wpas_dbus_getter_p2p_group(DBusMessageIter *iter, DBusError *error,
                                       void *user_data)
 {
        struct wpa_supplicant *wpa_s = user_data;
+       char path_buf[WPAS_DBUS_OBJECT_PATH_MAX];
+       char *dbus_groupobj_path = path_buf;
 
        if (wpa_s->dbus_groupobj_path == NULL)
-               return FALSE;
+               os_snprintf(dbus_groupobj_path, WPAS_DBUS_OBJECT_PATH_MAX,
+                           "/");
+       else
+               os_snprintf(dbus_groupobj_path, WPAS_DBUS_OBJECT_PATH_MAX,
+                           "%s", wpa_s->dbus_groupobj_path);
 
        return wpas_dbus_simple_property_getter(iter, DBUS_TYPE_OBJECT_PATH,
-                                               &wpa_s->dbus_groupobj_path,
-                                               error);
+                                               &dbus_groupobj_path, error);
 }
 
 
@@ -1157,11 +1158,13 @@ dbus_bool_t wpas_dbus_getter_p2p_peergo(DBusMessageIter *iter,
        char go_peer_obj_path[WPAS_DBUS_OBJECT_PATH_MAX], *path;
 
        if (wpas_get_p2p_role(wpa_s) != WPAS_P2P_ROLE_CLIENT)
-               return FALSE;
+               os_snprintf(go_peer_obj_path, WPAS_DBUS_OBJECT_PATH_MAX, "/");
+       else
+               os_snprintf(go_peer_obj_path, WPAS_DBUS_OBJECT_PATH_MAX,
+                           "%s/" WPAS_DBUS_NEW_P2P_PEERS_PART "/"
+                           COMPACT_MACSTR,
+                           wpa_s->dbus_new_path, MAC2STR(wpa_s->go_dev_addr));
 
-       os_snprintf(go_peer_obj_path, WPAS_DBUS_OBJECT_PATH_MAX,
-                   "%s/" WPAS_DBUS_NEW_P2P_PEERS_PART "/" COMPACT_MACSTR,
-                   wpa_s->dbus_new_path, MAC2STR(wpa_s->go_dev_addr));
        path = go_peer_obj_path;
        return wpas_dbus_simple_property_getter(iter, DBUS_TYPE_OBJECT_PATH,
                                                &path, error);
@@ -1506,7 +1509,7 @@ dbus_bool_t wpas_dbus_getter_persistent_groups(DBusMessageIter *iter,
                if (network_is_persistent_group(ssid))
                        num++;
 
-       paths = os_zalloc(num * sizeof(char *));
+       paths = os_calloc(num, sizeof(char *));
        if (!paths) {
                dbus_set_error_const(error, DBUS_ERROR_NO_MEMORY, "no memory");
                return FALSE;
@@ -1813,7 +1816,7 @@ dbus_bool_t wpas_dbus_getter_p2p_group_members(DBusMessageIter *iter,
 
        num_members = p2p_get_group_num_members(wpa_s->p2p_group);
 
-       paths = os_zalloc(num_members * sizeof(char *));
+       paths = os_calloc(num_members, sizeof(char *));
        if (!paths)
                goto out_of_memory;
 
@@ -2066,7 +2069,7 @@ DBusMessage * wpas_dbus_handler_p2p_add_service(DBusMessage *message,
        if (!wpa_dbus_dict_open_read(&iter, &iter_dict, NULL))
                goto error;
 
-       if (wpa_dbus_dict_has_dict_entry(&iter_dict)) {
+       while (wpa_dbus_dict_has_dict_entry(&iter_dict)) {
                if (!wpa_dbus_dict_get_entry(&iter_dict, &entry))
                        goto error;
 
@@ -2078,23 +2081,30 @@ DBusMessage * wpas_dbus_handler_p2p_add_service(DBusMessage *message,
                                bonjour = 1;
                        else
                                goto error_clear;
-                       wpa_dbus_dict_entry_clear(&entry);
+               } else if (!os_strcmp(entry.key, "version") &&
+                          entry.type == DBUS_TYPE_INT32) {
+                       version = entry.uint32_value;
+               } else if (!os_strcmp(entry.key, "service") &&
+                            (entry.type == DBUS_TYPE_STRING)) {
+                       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))
+                               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))
+                               goto error_clear;
+                       resp = wpabuf_alloc_copy(entry.bytearray_value,
+                                                entry.array_len);
                }
+               wpa_dbus_dict_entry_clear(&entry);
        }
 
        if (upnp == 1) {
-               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") &&
-                           entry.type == DBUS_TYPE_INT32)
-                               version = entry.uint32_value;
-                       else if (!os_strcmp(entry.key, "service") &&
-                                entry.type == DBUS_TYPE_STRING)
-                               service = os_strdup(entry.str_value);
-                       wpa_dbus_dict_entry_clear(&entry);
-               }
                if (version <= 0 || service == NULL)
                        goto error;
 
@@ -2102,37 +2112,15 @@ DBusMessage * wpas_dbus_handler_p2p_add_service(DBusMessage *message,
                        goto error;
 
                os_free(service);
+               service = NULL;
        } else if (bonjour == 1) {
-               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, "query")) {
-                               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))
-                                       goto error_clear;
-                               resp = wpabuf_alloc_copy(entry.bytearray_value,
-                                                        entry.array_len);
-                       }
-
-                       wpa_dbus_dict_entry_clear(&entry);
-               }
-
                if (query == NULL || resp == NULL)
                        goto error;
 
-               if (wpas_p2p_service_add_bonjour(wpa_s, query, resp) < 0) {
-                       wpabuf_free(query);
-                       wpabuf_free(resp);
+               if (wpas_p2p_service_add_bonjour(wpa_s, query, resp) < 0)
                        goto error;
-               }
+               query = NULL;
+               resp = NULL;
        } else
                goto error;
 
@@ -2140,6 +2128,9 @@ DBusMessage * wpas_dbus_handler_p2p_add_service(DBusMessage *message,
 error_clear:
        wpa_dbus_dict_entry_clear(&entry);
 error:
+       os_free(service);
+       wpabuf_free(query);
+       wpabuf_free(resp);
        return wpas_dbus_error_invalid_args(message, NULL);
 }
 
@@ -2258,7 +2249,7 @@ DBusMessage * wpas_dbus_handler_p2p_service_sd_req(
        struct wpabuf *tlv = NULL;
        u8 version = 0;
        u64 ref = 0;
-       u8 addr[ETH_ALEN];
+       u8 addr_buf[ETH_ALEN], *addr;
 
        dbus_message_iter_init(message, &iter);
 
@@ -2295,10 +2286,15 @@ DBusMessage * wpas_dbus_handler_p2p_service_sd_req(
                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 (!peer_object_path) {
+               addr = NULL;
+       } else {
+               if (parse_peer_object_path(peer_object_path, addr_buf) < 0 ||
+                   !p2p_peer_known(wpa_s->global->p2p, addr_buf))
+                       goto error;
+
+               addr = addr_buf;
+       }
 
        if (upnp == 1) {
                if (version <= 0 || service == NULL)