dbus_new_handlers.c
Go to the documentation of this file.
00001 /*
00002  * WPA Supplicant / dbus-based control interface
00003  * Copyright (c) 2006, Dan Williams <dcbw@redhat.com> and Red Hat, Inc.
00004  * Copyright (c) 2009-2010, Witold Sowa <witold.sowa@gmail.com>
00005  * Copyright (c) 2009, Jouni Malinen <j@w1.fi>
00006  *
00007  * This program is free software; you can redistribute it and/or modify
00008  * it under the terms of the GNU General Public License version 2 as
00009  * published by the Free Software Foundation.
00010  *
00011  * Alternatively, this software may be distributed under the terms of BSD
00012  * license.
00013  *
00014  * See README and COPYING for more details.
00015  */
00016 
00017 #include "includes.h"
00018 
00019 #include "common.h"
00020 #include "common/ieee802_11_defs.h"
00021 #include "eap_peer/eap_methods.h"
00022 #include "eapol_supp/eapol_supp_sm.h"
00023 #include "rsn_supp/wpa.h"
00024 #include "../config.h"
00025 #include "../wpa_supplicant_i.h"
00026 #include "../driver_i.h"
00027 #include "../notify.h"
00028 #include "../wpas_glue.h"
00029 #include "../bss.h"
00030 #include "../scan.h"
00031 #include "dbus_new_helpers.h"
00032 #include "dbus_new.h"
00033 #include "dbus_new_handlers.h"
00034 #include "dbus_dict_helpers.h"
00035 
00036 #include "../../../src/nodes/wpa_supplicant_node.h"
00037 
00038 extern int wpa_debug_level;
00039 extern int wpa_debug_show_keys;
00040 extern int wpa_debug_timestamp;
00041 
00042 static const char *debug_strings[] = {
00043         "msgdump", "debug", "info", "warning", "error", NULL
00044 };
00045 
00046 
00057 static char * wpas_dbus_new_decompose_object_path(const char *path,
00058                                                   char **network,
00059                                                   char **bssid)
00060 {
00061         const unsigned int dev_path_prefix_len =
00062                 strlen(WPAS_DBUS_NEW_PATH_INTERFACES "/");
00063         char *obj_path_only;
00064         char *next_sep;
00065 
00066         /* Be a bit paranoid about path */
00067         if (!path || os_strncmp(path, WPAS_DBUS_NEW_PATH_INTERFACES "/",
00068                                 dev_path_prefix_len))
00069                 return NULL;
00070 
00071         /* Ensure there's something at the end of the path */
00072         if ((path + dev_path_prefix_len)[0] == '\0')
00073                 return NULL;
00074 
00075         obj_path_only = os_strdup(path);
00076         if (obj_path_only == NULL)
00077                 return NULL;
00078 
00079         next_sep = os_strchr(obj_path_only + dev_path_prefix_len, '/');
00080         if (next_sep != NULL) {
00081                 const char *net_part = os_strstr(
00082                         next_sep, WPAS_DBUS_NEW_NETWORKS_PART "/");
00083                 const char *bssid_part = os_strstr(
00084                         next_sep, WPAS_DBUS_NEW_BSSIDS_PART "/");
00085 
00086                 if (network && net_part) {
00087                         /* Deal with a request for a configured network */
00088                         const char *net_name = net_part +
00089                                 os_strlen(WPAS_DBUS_NEW_NETWORKS_PART "/");
00090                         *network = NULL;
00091                         if (os_strlen(net_name))
00092                                 *network = os_strdup(net_name);
00093                 } else if (bssid && bssid_part) {
00094                         /* Deal with a request for a scanned BSSID */
00095                         const char *bssid_name = bssid_part +
00096                                 os_strlen(WPAS_DBUS_NEW_BSSIDS_PART "/");
00097                         if (strlen(bssid_name))
00098                                 *bssid = os_strdup(bssid_name);
00099                         else
00100                                 *bssid = NULL;
00101                 }
00102 
00103                 /* Cut off interface object path before "/" */
00104                 *next_sep = '\0';
00105         }
00106 
00107         return obj_path_only;
00108 }
00109 
00110 
00119 DBusMessage * wpas_dbus_error_unknown_error(DBusMessage *message,
00120                                             const char *arg)
00121 {
00122         return dbus_message_new_error(message, WPAS_DBUS_ERROR_UNKNOWN_ERROR,
00123                                       arg);
00124 }
00125 
00126 
00134 static DBusMessage * wpas_dbus_error_iface_unknown(DBusMessage *message)
00135 {
00136         return dbus_message_new_error(message, WPAS_DBUS_ERROR_IFACE_UNKNOWN,
00137                                       "wpa_supplicant knows nothing about "
00138                                       "this interface.");
00139 }
00140 
00141 
00149 static DBusMessage * wpas_dbus_error_network_unknown(DBusMessage *message)
00150 {
00151         return dbus_message_new_error(message, WPAS_DBUS_ERROR_NETWORK_UNKNOWN,
00152                                       "There is no such a network in this "
00153                                       "interface.");
00154 }
00155 
00156 
00164 DBusMessage * wpas_dbus_error_invalid_args(DBusMessage *message,
00165                                           const char *arg)
00166 {
00167         DBusMessage *reply;
00168 
00169         reply = dbus_message_new_error(message, WPAS_DBUS_ERROR_INVALID_ARGS,
00170                                        "Did not receive correct message "
00171                                        "arguments.");
00172         if (arg != NULL)
00173                 dbus_message_append_args(reply, DBUS_TYPE_STRING, &arg,
00174                                          DBUS_TYPE_INVALID);
00175 
00176         return reply;
00177 }
00178 
00179 
00180 static const char *dont_quote[] = {
00181         "key_mgmt", "proto", "pairwise", "auth_alg", "group", "eap",
00182         "opensc_engine_path", "pkcs11_engine_path", "pkcs11_module_path",
00183         "bssid", NULL
00184 };
00185 
00186 static dbus_bool_t should_quote_opt(const char *key)
00187 {
00188         int i = 0;
00189         while (dont_quote[i] != NULL) {
00190                 if (os_strcmp(key, dont_quote[i]) == 0)
00191                         return FALSE;
00192                 i++;
00193         }
00194         return TRUE;
00195 }
00196 
00203 static struct wpa_supplicant * get_iface_by_dbus_path(
00204         struct wpa_global *global, const char *path)
00205 {
00206         struct wpa_supplicant *wpa_s;
00207 
00208         for (wpa_s = global->ifaces; wpa_s; wpa_s = wpa_s->next) {
00209                 if (os_strcmp(wpa_s->dbus_new_path, path) == 0)
00210                         return wpa_s;
00211         }
00212         return NULL;
00213 }
00214 
00215 
00227 static DBusMessage * set_network_properties(DBusMessage *message,
00228                                             struct wpa_supplicant *wpa_s,
00229                                             struct wpa_ssid *ssid,
00230                                             DBusMessageIter *iter)
00231 {
00232 
00233         struct wpa_dbus_dict_entry entry = { .type = DBUS_TYPE_STRING };
00234         DBusMessage *reply = NULL;
00235         DBusMessageIter iter_dict;
00236 
00237         if (!wpa_dbus_dict_open_read(iter, &iter_dict))
00238                 return wpas_dbus_error_invalid_args(message, NULL);
00239 
00240         while (wpa_dbus_dict_has_dict_entry(&iter_dict)) {
00241                 char *value = NULL;
00242                 size_t size = 50;
00243                 int ret;
00244                 if (!wpa_dbus_dict_get_entry(&iter_dict, &entry)) {
00245                         reply = wpas_dbus_error_invalid_args(message, NULL);
00246                         break;
00247                 }
00248                 if (entry.type == DBUS_TYPE_ARRAY &&
00249                     entry.array_type == DBUS_TYPE_BYTE) {
00250                         if (entry.array_len <= 0)
00251                                 goto error;
00252 
00253                         size = entry.array_len * 2 + 1;
00254                         value = os_zalloc(size);
00255                         if (value == NULL)
00256                                 goto error;
00257 
00258                         ret = wpa_snprintf_hex(value, size,
00259                                                (u8 *) entry.bytearray_value,
00260                                                entry.array_len);
00261                         if (ret <= 0)
00262                                 goto error;
00263                 } else if (entry.type == DBUS_TYPE_STRING) {
00264                         if (should_quote_opt(entry.key)) {
00265                                 size = os_strlen(entry.str_value);
00266                                 if (size <= 0)
00267                                         goto error;
00268 
00269                                 size += 3;
00270                                 value = os_zalloc(size);
00271                                 if (value == NULL)
00272                                         goto error;
00273 
00274                                 ret = os_snprintf(value, size, "\"%s\"",
00275                                                   entry.str_value);
00276                                 if (ret < 0 || (size_t) ret != (size - 1))
00277                                         goto error;
00278                         } else {
00279                                 value = os_strdup(entry.str_value);
00280                                 if (value == NULL)
00281                                         goto error;
00282                         }
00283                 } else if (entry.type == DBUS_TYPE_UINT32) {
00284                         value = os_zalloc(size);
00285                         if (value == NULL)
00286                                 goto error;
00287 
00288                         ret = os_snprintf(value, size, "%u",
00289                                           entry.uint32_value);
00290                         if (ret <= 0)
00291                                 goto error;
00292                 } else if (entry.type == DBUS_TYPE_INT32) {
00293                         value = os_zalloc(size);
00294                         if (value == NULL)
00295                                 goto error;
00296 
00297                         ret = os_snprintf(value, size, "%d",
00298                                           entry.int32_value);
00299                         if (ret <= 0)
00300                                 goto error;
00301                 } else
00302                         goto error;
00303 
00304                 if (wpa_config_set(ssid, entry.key, value, 0) < 0)
00305                         goto error;
00306 
00307                 if ((os_strcmp(entry.key, "psk") == 0 &&
00308                      value[0] == '"' && ssid->ssid_len) ||
00309                     (strcmp(entry.key, "ssid") == 0 && ssid->passphrase))
00310                         wpa_config_update_psk(ssid);
00311                 else if (os_strcmp(entry.key, "priority") == 0)
00312                         wpa_config_update_prio_list(wpa_s->conf);
00313 
00314                 os_free(value);
00315                 wpa_dbus_dict_entry_clear(&entry);
00316                 continue;
00317 
00318         error:
00319                 os_free(value);
00320                 reply = wpas_dbus_error_invalid_args(message, entry.key);
00321                 wpa_dbus_dict_entry_clear(&entry);
00322                 break;
00323         }
00324 
00325         return reply;
00326 }
00327 
00328 
00339 DBusMessage * wpas_dbus_simple_property_getter(DBusMessage *message,
00340                                                const int type, const void *val)
00341 {
00342         DBusMessage *reply = NULL;
00343         DBusMessageIter iter, variant_iter;
00344 
00345         if (!dbus_type_is_basic(type)) {
00346                 wpa_printf(MSG_ERROR, "dbus: wpas_dbus_simple_property_getter:"
00347                            " given type is not basic");
00348                 return wpas_dbus_error_unknown_error(message, NULL);
00349         }
00350 
00351         if (message == NULL)
00352                 reply = dbus_message_new(DBUS_MESSAGE_TYPE_SIGNAL);
00353         else
00354                 reply = dbus_message_new_method_return(message);
00355 
00356         if (reply != NULL) {
00357                 dbus_message_iter_init_append(reply, &iter);
00358                 if (!dbus_message_iter_open_container(
00359                             &iter, DBUS_TYPE_VARIANT,
00360                             wpa_dbus_type_as_string(type), &variant_iter) ||
00361                     !dbus_message_iter_append_basic(&variant_iter, type,
00362                                                     val) ||
00363                     !dbus_message_iter_close_container(&iter, &variant_iter)) {
00364                         wpa_printf(MSG_ERROR, "dbus: "
00365                                    "wpas_dbus_simple_property_getter: out of "
00366                                    "memory to put property value into "
00367                                    "message");
00368                         dbus_message_unref(reply);
00369                         reply = dbus_message_new_error(message,
00370                                                        DBUS_ERROR_NO_MEMORY,
00371                                                        NULL);
00372                 }
00373         } else {
00374                 wpa_printf(MSG_ERROR, "dbus: wpas_dbus_simple_property_getter:"
00375                            " out of memory to return property value");
00376                 reply = dbus_message_new_error(message, DBUS_ERROR_NO_MEMORY,
00377                                                NULL);
00378         }
00379 
00380         return reply;
00381 }
00382 
00383 
00393 DBusMessage * wpas_dbus_simple_property_setter(DBusMessage *message,
00394                                                const int type, void *val)
00395 {
00396         DBusMessageIter iter, variant_iter;
00397 
00398         if (!dbus_type_is_basic(type)) {
00399                 wpa_printf(MSG_ERROR, "dbus: wpas_dbus_simple_property_setter:"
00400                            " given type is not basic");
00401                 return wpas_dbus_error_unknown_error(message, NULL);
00402         }
00403 
00404         if (!dbus_message_iter_init(message, &iter)) {
00405                 wpa_printf(MSG_ERROR, "dbus: wpas_dbus_simple_property_setter:"
00406                            " out of memory to return scanning state");
00407                 return dbus_message_new_error(message, DBUS_ERROR_NO_MEMORY,
00408                                               NULL);
00409         }
00410 
00411         /* omit first and second argument and get value from third */
00412         dbus_message_iter_next(&iter);
00413         dbus_message_iter_next(&iter);
00414         dbus_message_iter_recurse(&iter, &variant_iter);
00415 
00416         if (dbus_message_iter_get_arg_type(&variant_iter) != type) {
00417                 wpa_printf(MSG_DEBUG, "dbus: wpas_dbus_simple_property_setter:"
00418                            " wrong property type");
00419                 return wpas_dbus_error_invalid_args(message,
00420                                                     "wrong property type");
00421         }
00422         dbus_message_iter_get_basic(&variant_iter, val);
00423 
00424         return NULL;
00425 }
00426 
00427 
00440 DBusMessage * wpas_dbus_simple_array_property_getter(DBusMessage *message,
00441                                                      const int type,
00442                                                      const void *array,
00443                                                      size_t array_len)
00444 {
00445         DBusMessage *reply = NULL;
00446         DBusMessageIter iter, variant_iter, array_iter;
00447         char type_str[] = "a?"; /* ? will be replaced with subtype letter; */
00448         const char *sub_type_str;
00449         size_t element_size, i;
00450 
00451         if (!dbus_type_is_basic(type)) {
00452                 wpa_printf(MSG_ERROR, "dbus: "
00453                            "wpas_dbus_simple_array_property_getter: given "
00454                            "type is not basic");
00455                 return wpas_dbus_error_unknown_error(message, NULL);
00456         }
00457 
00458         sub_type_str = wpa_dbus_type_as_string(type);
00459         type_str[1] = sub_type_str[0];
00460 
00461         if (message == NULL)
00462                 reply = dbus_message_new(DBUS_MESSAGE_TYPE_SIGNAL);
00463         else
00464                 reply = dbus_message_new_method_return(message);
00465         if (reply == NULL) {
00466                 wpa_printf(MSG_ERROR, "dbus: "
00467                            "wpas_dbus_simple_array_property_getter: out of "
00468                            "memory to create return message");
00469                 return dbus_message_new_error(message, DBUS_ERROR_NO_MEMORY,
00470                                               NULL);
00471         }
00472 
00473         dbus_message_iter_init_append(reply, &iter);
00474 
00475         if (!dbus_message_iter_open_container(&iter, DBUS_TYPE_VARIANT,
00476                                               type_str, &variant_iter) ||
00477             !dbus_message_iter_open_container(&variant_iter, DBUS_TYPE_ARRAY,
00478                                               sub_type_str, &array_iter)) {
00479                 wpa_printf(MSG_ERROR, "dbus: "
00480                            "wpas_dbus_simple_array_property_getter: out of "
00481                            "memory to open container");
00482                 dbus_message_unref(reply);
00483                 return dbus_message_new_error(message, DBUS_ERROR_NO_MEMORY,
00484                                               NULL);
00485         }
00486 
00487         switch(type) {
00488         case DBUS_TYPE_BYTE:
00489         case DBUS_TYPE_BOOLEAN:
00490                 element_size = 1;
00491                 break;
00492         case DBUS_TYPE_INT16:
00493         case DBUS_TYPE_UINT16:
00494                 element_size = sizeof(uint16_t);
00495                 break;
00496         case DBUS_TYPE_INT32:
00497         case DBUS_TYPE_UINT32:
00498                 element_size = sizeof(uint32_t);
00499                 break;
00500         case DBUS_TYPE_INT64:
00501         case DBUS_TYPE_UINT64:
00502                 element_size = sizeof(uint64_t);
00503                 break;
00504         case DBUS_TYPE_DOUBLE:
00505                 element_size = sizeof(double);
00506                 break;
00507         case DBUS_TYPE_STRING:
00508         case DBUS_TYPE_OBJECT_PATH:
00509                 element_size = sizeof(char *);
00510                 break;
00511         default:
00512                 wpa_printf(MSG_ERROR, "dbus: "
00513                            "wpas_dbus_simple_array_property_getter: "
00514                            "fatal: unknown element type");
00515                 element_size = 1;
00516                 break;
00517         }
00518 
00519         for (i = 0; i < array_len; i++) {
00520                 dbus_message_iter_append_basic(&array_iter, type,
00521                                                array + i * element_size);
00522         }
00523 
00524         if (!dbus_message_iter_close_container(&variant_iter, &array_iter) ||
00525             !dbus_message_iter_close_container(&iter, &variant_iter)) {
00526                 wpa_printf(MSG_ERROR, "dbus: "
00527                            "wpas_dbus_simple_array_property_getter: out of "
00528                            "memory to close container");
00529                 dbus_message_unref(reply);
00530                 return dbus_message_new_error(message, DBUS_ERROR_NO_MEMORY,
00531                                               NULL);
00532         }
00533 
00534         return reply;
00535 }
00536 
00537 
00549 DBusMessage * wpas_dbus_handler_create_interface(DBusMessage *message,
00550                                                  struct wpa_global *global)
00551 {
00552         DBusMessageIter iter_dict;
00553         DBusMessage *reply = NULL;
00554         DBusMessageIter iter;
00555         struct wpa_dbus_dict_entry entry;
00556         char *driver = NULL;
00557         char *ifname = NULL;
00558         char *bridge_ifname = NULL;
00559 
00560         dbus_message_iter_init(message, &iter);
00561 
00562         if (!wpa_dbus_dict_open_read(&iter, &iter_dict))
00563                 goto error;
00564         while (wpa_dbus_dict_has_dict_entry(&iter_dict)) {
00565                 if (!wpa_dbus_dict_get_entry(&iter_dict, &entry))
00566                         goto error;
00567                 if (!strcmp(entry.key, "Driver") &&
00568                     (entry.type == DBUS_TYPE_STRING)) {
00569                         driver = os_strdup(entry.str_value);
00570                         wpa_dbus_dict_entry_clear(&entry);
00571                         if (driver == NULL)
00572                                 goto error;
00573                 } else if (!strcmp(entry.key, "Ifname") &&
00574                            (entry.type == DBUS_TYPE_STRING)) {
00575                         ifname = os_strdup(entry.str_value);
00576                         wpa_dbus_dict_entry_clear(&entry);
00577                         if (ifname == NULL)
00578                                 goto error;
00579                 } else if (!strcmp(entry.key, "BridgeIfname") &&
00580                            (entry.type == DBUS_TYPE_STRING)) {
00581                         bridge_ifname = os_strdup(entry.str_value);
00582                         wpa_dbus_dict_entry_clear(&entry);
00583                         if (bridge_ifname == NULL)
00584                                 goto error;
00585                 } else {
00586                         wpa_dbus_dict_entry_clear(&entry);
00587                         goto error;
00588                 }
00589         }
00590 
00591         if (ifname == NULL)
00592                 goto error; /* Required Ifname argument missing */
00593 
00594         /*
00595          * Try to get the wpa_supplicant record for this iface, return
00596          * an error if we already control it.
00597          */
00598         if (wpa_supplicant_get_iface(global, ifname) != NULL) {
00599                 reply = dbus_message_new_error(message,
00600                                                WPAS_DBUS_ERROR_IFACE_EXISTS,
00601                                                "wpa_supplicant already "
00602                                                "controls this interface.");
00603         } else {
00604                 struct wpa_supplicant *wpa_s;
00605                 struct wpa_interface iface;
00606                 os_memset(&iface, 0, sizeof(iface));
00607                 iface.driver = driver;
00608                 iface.ifname = ifname;
00609                 iface.bridge_ifname = bridge_ifname;
00610                 /* Otherwise, have wpa_supplicant attach to it. */
00611                 if ((wpa_s = wpa_supplicant_add_iface(global, &iface))) {
00612                         const char *path = wpa_s->dbus_new_path;
00613                         reply = dbus_message_new_method_return(message);
00614                         dbus_message_append_args(reply, DBUS_TYPE_OBJECT_PATH,
00615                                                  &path, DBUS_TYPE_INVALID);
00616                 } else {
00617                         reply = wpas_dbus_error_unknown_error(
00618                                 message, "wpa_supplicant couldn't grab this "
00619                                 "interface.");
00620                 }
00621         }
00622 
00623 out:
00624         os_free(driver);
00625         os_free(ifname);
00626         os_free(bridge_ifname);
00627         return reply;
00628 
00629 error:
00630         reply = wpas_dbus_error_invalid_args(message, NULL);
00631         goto out;
00632 }
00633 
00634 
00646 DBusMessage * wpas_dbus_handler_remove_interface(DBusMessage *message,
00647                                                  struct wpa_global *global)
00648 {
00649         struct wpa_supplicant *wpa_s;
00650         char *path;
00651         DBusMessage *reply = NULL;
00652 
00653         dbus_message_get_args(message, NULL, DBUS_TYPE_OBJECT_PATH, &path,
00654                               DBUS_TYPE_INVALID);
00655 
00656         wpa_s = get_iface_by_dbus_path(global, path);
00657         if (wpa_s == NULL)
00658                 reply = wpas_dbus_error_iface_unknown(message);
00659         else if (wpa_supplicant_remove_iface(global, wpa_s)) {
00660                 reply = wpas_dbus_error_unknown_error(
00661                         message, "wpa_supplicant couldn't remove this "
00662                         "interface.");
00663         }
00664 
00665         return reply;
00666 }
00667 
00668 
00678 DBusMessage * wpas_dbus_handler_get_interface(DBusMessage *message,
00679                                               struct wpa_global *global)
00680 {
00681         DBusMessage *reply = NULL;
00682         const char *ifname;
00683         const char *path;
00684         struct wpa_supplicant *wpa_s;
00685 
00686         dbus_message_get_args(message, NULL, DBUS_TYPE_STRING, &ifname,
00687                               DBUS_TYPE_INVALID);
00688 
00689         wpa_s = wpa_supplicant_get_iface(global, ifname);
00690         if (wpa_s == NULL)
00691                 return wpas_dbus_error_iface_unknown(message);
00692 
00693         path = wpa_s->dbus_new_path;
00694         reply = dbus_message_new_method_return(message);
00695         if (reply == NULL)
00696                 return dbus_message_new_error(message, DBUS_ERROR_NO_MEMORY,
00697                                               NULL);
00698         if (!dbus_message_append_args(reply, DBUS_TYPE_OBJECT_PATH, &path,
00699                                       DBUS_TYPE_INVALID)) {
00700                 dbus_message_unref(reply);
00701                 return dbus_message_new_error(message, DBUS_ERROR_NO_MEMORY,
00702                                               NULL);
00703         }
00704 
00705         return reply;
00706 }
00707 
00708 
00717 DBusMessage * wpas_dbus_getter_debug_level(DBusMessage *message,
00718                                            struct wpa_global *global)
00719 {
00720         const char *str;
00721         int idx = wpa_debug_level;
00722         if (idx < 0)
00723                 idx = 0;
00724         if (idx > 4)
00725                 idx = 4;
00726         str = debug_strings[idx];
00727         return wpas_dbus_simple_property_getter(message, DBUS_TYPE_STRING,
00728                                                 &str);
00729 }
00730 
00731 
00740 DBusMessage * wpas_dbus_getter_debug_timestamp(DBusMessage *message,
00741                                                struct wpa_global *global)
00742 {
00743         return wpas_dbus_simple_property_getter(message, DBUS_TYPE_BOOLEAN,
00744                                                 &wpa_debug_timestamp);
00745 
00746 }
00747 
00748 
00757 DBusMessage * wpas_dbus_getter_debug_show_keys(DBusMessage *message,
00758                                                struct wpa_global *global)
00759 {
00760         return wpas_dbus_simple_property_getter(message, DBUS_TYPE_BOOLEAN,
00761                                                 &wpa_debug_show_keys);
00762 
00763 }
00764 
00773 DBusMessage * wpas_dbus_setter_debug_level(DBusMessage *message,
00774                                            struct wpa_global *global)
00775 {
00776         DBusMessage *reply;
00777         const char *str = NULL;
00778         int i, val = -1;
00779 
00780         reply = wpas_dbus_simple_property_setter(message, DBUS_TYPE_STRING,
00781                                                  &str);
00782         if (reply)
00783                 return reply;
00784 
00785         for (i = 0; debug_strings[i]; i++)
00786                 if (os_strcmp(debug_strings[i], str) == 0) {
00787                         val = i;
00788                         break;
00789                 }
00790 
00791         if (val < 0 ||
00792             wpa_supplicant_set_debug_params(global, val, wpa_debug_timestamp,
00793                                             wpa_debug_show_keys)) {
00794                 dbus_message_unref(reply);
00795                 return wpas_dbus_error_invalid_args(
00796                         message, "Wrong debug level value");
00797         }
00798 
00799         return NULL;
00800 }
00801 
00802 
00811 DBusMessage * wpas_dbus_setter_debug_timestamp(DBusMessage *message,
00812                                                struct wpa_global *global)
00813 {
00814         DBusMessage *reply;
00815         dbus_bool_t val;
00816 
00817         reply = wpas_dbus_simple_property_setter(message, DBUS_TYPE_BOOLEAN,
00818                                                  &val);
00819         if (reply)
00820                 return reply;
00821 
00822         wpa_supplicant_set_debug_params(global, wpa_debug_level, val ? 1 : 0,
00823                                         wpa_debug_show_keys);
00824 
00825         return NULL;
00826 }
00827 
00828 
00837 DBusMessage * wpas_dbus_setter_debug_show_keys(DBusMessage *message,
00838                                                struct wpa_global *global)
00839 {
00840         DBusMessage *reply;
00841         dbus_bool_t val;
00842 
00843         reply = wpas_dbus_simple_property_setter(message, DBUS_TYPE_BOOLEAN,
00844                                                  &val);
00845         if (reply)
00846                 return reply;
00847 
00848         wpa_supplicant_set_debug_params(global, wpa_debug_level,
00849                                         wpa_debug_timestamp,
00850                                         val ? 1 : 0);
00851 
00852         return NULL;
00853 }
00854 
00855 
00867 DBusMessage * wpas_dbus_getter_interfaces(DBusMessage *message,
00868                                           struct wpa_global *global)
00869 {
00870         DBusMessage *reply = NULL;
00871         struct wpa_supplicant *wpa_s;
00872         const char **paths;
00873         unsigned int i = 0, num = 0;
00874 
00875         for (wpa_s = global->ifaces; wpa_s; wpa_s = wpa_s->next)
00876                 num++;
00877 
00878         paths = os_zalloc(num * sizeof(char*));
00879         if (!paths) {
00880                 return dbus_message_new_error(message, DBUS_ERROR_NO_MEMORY,
00881                                               NULL);
00882         }
00883 
00884         for (wpa_s = global->ifaces; wpa_s; wpa_s = wpa_s->next)
00885                 paths[i++] = wpa_s->dbus_new_path;
00886 
00887         reply = wpas_dbus_simple_array_property_getter(message,
00888                                                        DBUS_TYPE_OBJECT_PATH,
00889                                                        paths, num);
00890 
00891         os_free(paths);
00892         return reply;
00893 }
00894 
00895 
00906 DBusMessage * wpas_dbus_getter_eap_methods(DBusMessage *message, void *nothing)
00907 {
00908         DBusMessage *reply = NULL;
00909         char **eap_methods;
00910         size_t num_items = 0;
00911 
00912         eap_methods = eap_get_names_as_string_array(&num_items);
00913         if (!eap_methods) {
00914                 return dbus_message_new_error(message, DBUS_ERROR_NO_MEMORY,
00915                                               NULL);
00916         }
00917 
00918         reply = wpas_dbus_simple_array_property_getter(message,
00919                                                        DBUS_TYPE_STRING,
00920                                                        eap_methods, num_items);
00921 
00922         while (num_items)
00923                 os_free(eap_methods[--num_items]);
00924         os_free(eap_methods);
00925         return reply;
00926 }
00927 
00928 
00929 static int wpas_dbus_get_scan_type(DBusMessage *message, DBusMessageIter *var,
00930                                    char **type, DBusMessage **reply)
00931 {
00932         if (dbus_message_iter_get_arg_type(var) != DBUS_TYPE_STRING) {
00933                 wpa_printf(MSG_DEBUG, "wpas_dbus_handler_scan[dbus]: "
00934                            "Type must be a string");
00935                 *reply = wpas_dbus_error_invalid_args(
00936                         message, "Wrong Type value type. String required");
00937                 return -1;
00938         }
00939         dbus_message_iter_get_basic(var, type);
00940         return 0;
00941 }
00942 
00943 
00944 static int wpas_dbus_get_scan_ssids(DBusMessage *message, DBusMessageIter *var,
00945                                     struct wpa_driver_scan_params *params,
00946                                     DBusMessage **reply)
00947 {
00948         struct wpa_driver_scan_ssid *ssids = params->ssids;
00949         size_t ssids_num = 0;
00950         u8 *ssid;
00951         DBusMessageIter array_iter, sub_array_iter;
00952         char *val;
00953         int len;
00954 
00955         if (dbus_message_iter_get_arg_type(var) != DBUS_TYPE_ARRAY) {
00956                 wpa_printf(MSG_DEBUG, "wpas_dbus_handler_scan[dbus]: ssids "
00957                            "must be an array of arrays of bytes");
00958                 *reply = wpas_dbus_error_invalid_args(
00959                         message, "Wrong SSIDs value type. Array of arrays of "
00960                         "bytes required");
00961                 return -1;
00962         }
00963 
00964         dbus_message_iter_recurse(var, &array_iter);
00965 
00966         if (dbus_message_iter_get_arg_type(&array_iter) != DBUS_TYPE_ARRAY ||
00967             dbus_message_iter_get_element_type(&array_iter) != DBUS_TYPE_BYTE)
00968         {
00969                 wpa_printf(MSG_DEBUG, "wpas_dbus_handler_scan[dbus]: ssids "
00970                            "must be an array of arrays of bytes");
00971                 *reply = wpas_dbus_error_invalid_args(
00972                         message, "Wrong SSIDs value type. Array of arrays of "
00973                         "bytes required");
00974                 return -1;
00975         }
00976 
00977         while (dbus_message_iter_get_arg_type(&array_iter) == DBUS_TYPE_ARRAY)
00978         {
00979                 if (ssids_num >= WPAS_MAX_SCAN_SSIDS) {
00980                         wpa_printf(MSG_DEBUG, "wpas_dbus_handler_scan[dbus]: "
00981                                    "Too many ssids specified on scan dbus "
00982                                    "call");
00983                         *reply = wpas_dbus_error_invalid_args(
00984                                 message, "Too many ssids specified. Specify "
00985                                 "at most four");
00986                         return -1;
00987                 }
00988 
00989                 dbus_message_iter_recurse(&array_iter, &sub_array_iter);
00990 
00991                 dbus_message_iter_get_fixed_array(&sub_array_iter, &val, &len);
00992                 if (len == 0) {
00993                         dbus_message_iter_next(&array_iter);
00994                         continue;
00995                 }
00996 
00997                 ssid = os_malloc(len);
00998                 if (ssid == NULL) {
00999                         wpa_printf(MSG_DEBUG, "wpas_dbus_handler_scan[dbus]: "
01000                                    "out of memory. Cannot allocate memory for "
01001                                    "SSID");
01002                         *reply = dbus_message_new_error(
01003                                 message, DBUS_ERROR_NO_MEMORY, NULL);
01004                         return -1;
01005                 }
01006                 os_memcpy(ssid, val, len);
01007                 ssids[ssids_num].ssid = ssid;
01008                 ssids[ssids_num].ssid_len = len;
01009 
01010                 dbus_message_iter_next(&array_iter);
01011                 ssids_num++;
01012         }
01013 
01014         params->num_ssids = ssids_num;
01015         return 0;
01016 }
01017 
01018 
01019 static int wpas_dbus_get_scan_ies(DBusMessage *message, DBusMessageIter *var,
01020                                   struct wpa_driver_scan_params *params,
01021                                   DBusMessage **reply)
01022 {
01023         u8 *ies = NULL, *nies;
01024         int ies_len = 0;
01025         DBusMessageIter array_iter, sub_array_iter;
01026         char *val;
01027         int len;
01028 
01029         if (dbus_message_iter_get_arg_type(var) != DBUS_TYPE_ARRAY) {
01030                 wpa_printf(MSG_DEBUG, "wpas_dbus_handler_scan[dbus]: ies must "
01031                            "be an array of arrays of bytes");
01032                 *reply = wpas_dbus_error_invalid_args(
01033                         message, "Wrong IEs value type. Array of arrays of "
01034                         "bytes required");
01035                 return -1;
01036         }
01037 
01038         dbus_message_iter_recurse(var, &array_iter);
01039 
01040         if (dbus_message_iter_get_arg_type(&array_iter) != DBUS_TYPE_ARRAY ||
01041             dbus_message_iter_get_element_type(&array_iter) != DBUS_TYPE_BYTE)
01042         {
01043                 wpa_printf(MSG_DEBUG, "wpas_dbus_handler_scan[dbus]: ies must "
01044                            "be an array of arrays of bytes");
01045                 *reply = wpas_dbus_error_invalid_args(
01046                         message, "Wrong IEs value type. Array required");
01047                 return -1;
01048         }
01049 
01050         while (dbus_message_iter_get_arg_type(&array_iter) == DBUS_TYPE_ARRAY)
01051         {
01052                 dbus_message_iter_recurse(&array_iter, &sub_array_iter);
01053 
01054                 dbus_message_iter_get_fixed_array(&sub_array_iter, &val, &len);
01055                 if (len == 0) {
01056                         dbus_message_iter_next(&array_iter);
01057                         continue;
01058                 }
01059 
01060                 nies = os_realloc(ies, ies_len + len);
01061                 if (nies == NULL) {
01062                         wpa_printf(MSG_DEBUG, "wpas_dbus_handler_scan[dbus]: "
01063                                    "out of memory. Cannot allocate memory for "
01064                                    "IE");
01065                         os_free(ies);
01066                         *reply = dbus_message_new_error(
01067                                 message, DBUS_ERROR_NO_MEMORY, NULL);
01068                         return -1;
01069                 }
01070                 ies = nies;
01071                 os_memcpy(ies + ies_len, val, len);
01072                 ies_len += len;
01073 
01074                 dbus_message_iter_next(&array_iter);
01075         }
01076 
01077         params->extra_ies = ies;
01078         params->extra_ies_len = ies_len;
01079         return 0;
01080 }
01081 
01082 
01083 static int wpas_dbus_get_scan_channels(DBusMessage *message,
01084                                        DBusMessageIter *var,
01085                                        struct wpa_driver_scan_params *params,
01086                                        DBusMessage **reply)
01087 {
01088         DBusMessageIter array_iter, sub_array_iter;
01089         int *freqs = NULL, *nfreqs;
01090         int freqs_num = 0;
01091 
01092         if (dbus_message_iter_get_arg_type(var) != DBUS_TYPE_ARRAY) {
01093                 wpa_printf(MSG_DEBUG, "wpas_dbus_handler_scan[dbus]: "
01094                            "Channels must be an array of structs");
01095                 *reply = wpas_dbus_error_invalid_args(
01096                         message, "Wrong Channels value type. Array of structs "
01097                         "required");
01098                 return -1;
01099         }
01100 
01101         dbus_message_iter_recurse(var, &array_iter);
01102 
01103         if (dbus_message_iter_get_arg_type(&array_iter) != DBUS_TYPE_STRUCT) {
01104                 wpa_printf(MSG_DEBUG,
01105                            "wpas_dbus_handler_scan[dbus]: Channels must be an "
01106                            "array of structs");
01107                 *reply = wpas_dbus_error_invalid_args(
01108                         message, "Wrong Channels value type. Array of structs "
01109                         "required");
01110                 return -1;
01111         }
01112 
01113         while (dbus_message_iter_get_arg_type(&array_iter) == DBUS_TYPE_STRUCT)
01114         {
01115                 int freq, width;
01116 
01117                 dbus_message_iter_recurse(&array_iter, &sub_array_iter);
01118 
01119                 if (dbus_message_iter_get_arg_type(&sub_array_iter) !=
01120                     DBUS_TYPE_UINT32) {
01121                         wpa_printf(MSG_DEBUG, "wpas_dbus_handler_scan[dbus]: "
01122                                    "Channel must by specified by struct of "
01123                                    "two UINT32s %c",
01124                                    dbus_message_iter_get_arg_type(
01125                                            &sub_array_iter));
01126                         *reply = wpas_dbus_error_invalid_args(
01127                                 message, "Wrong Channel struct. Two UINT32s "
01128                                 "required");
01129                         os_free(freqs);
01130                         return -1;
01131                 }
01132                 dbus_message_iter_get_basic(&sub_array_iter, &freq);
01133 
01134                 if (!dbus_message_iter_next(&sub_array_iter) ||
01135                     dbus_message_iter_get_arg_type(&sub_array_iter) !=
01136                     DBUS_TYPE_UINT32) {
01137                         wpa_printf(MSG_DEBUG, "wpas_dbus_handler_scan[dbus]: "
01138                                    "Channel must by specified by struct of "
01139                                    "two UINT32s");
01140                         *reply = wpas_dbus_error_invalid_args(
01141                                 message,
01142                                 "Wrong Channel struct. Two UINT32s required");
01143                         os_free(freqs);
01144                         return -1;
01145                 }
01146 
01147                 dbus_message_iter_get_basic(&sub_array_iter, &width);
01148 
01149 #define FREQS_ALLOC_CHUNK 32
01150                 if (freqs_num % FREQS_ALLOC_CHUNK == 0) {
01151                         nfreqs = os_realloc(freqs, sizeof(int) *
01152                                             (freqs_num + FREQS_ALLOC_CHUNK));
01153                         if (nfreqs == NULL)
01154                                 os_free(freqs);
01155                         freqs = nfreqs;
01156                 }
01157                 if (freqs == NULL) {
01158                         wpa_printf(MSG_DEBUG, "wpas_dbus_handler_scan[dbus]: "
01159                                    "out of memory. can't allocate memory for "
01160                                    "freqs");
01161                         *reply = dbus_message_new_error(
01162                                 message, DBUS_ERROR_NO_MEMORY, NULL);
01163                         return -1;
01164                 }
01165 
01166                 freqs[freqs_num] = freq;
01167 
01168                 freqs_num++;
01169                 dbus_message_iter_next(&array_iter);
01170         }
01171 
01172         nfreqs = os_realloc(freqs,
01173                             sizeof(int) * (freqs_num + 1));
01174         if (nfreqs == NULL)
01175                 os_free(freqs);
01176         freqs = nfreqs;
01177         if (freqs == NULL) {
01178                 wpa_printf(MSG_DEBUG, "wpas_dbus_handler_scan[dbus]: "
01179                            "out of memory. Can't allocate memory for freqs");
01180                 *reply = dbus_message_new_error(
01181                         message, DBUS_ERROR_NO_MEMORY, NULL);
01182                 return -1;
01183         }
01184         freqs[freqs_num] = 0;
01185 
01186         params->freqs = freqs;
01187         return 0;
01188 }
01189 
01190 
01201 DBusMessage * wpas_dbus_handler_scan(DBusMessage *message,
01202                                      struct wpa_supplicant *wpa_s)
01203 {
01204         DBusMessage *reply = NULL;
01205         DBusMessageIter iter, dict_iter, entry_iter, variant_iter;
01206         char *key = NULL, *type = NULL;
01207         struct wpa_driver_scan_params params;
01208         size_t i;
01209 
01210         os_memset(&params, 0, sizeof(params));
01211 
01212         dbus_message_iter_init(message, &iter);
01213 
01214         dbus_message_iter_recurse(&iter, &dict_iter);
01215 
01216         while (dbus_message_iter_get_arg_type(&dict_iter) ==
01217                         DBUS_TYPE_DICT_ENTRY) {
01218                 dbus_message_iter_recurse(&dict_iter, &entry_iter);
01219                 dbus_message_iter_get_basic(&entry_iter, &key);
01220                 dbus_message_iter_next(&entry_iter);
01221                 dbus_message_iter_recurse(&entry_iter, &variant_iter);
01222 
01223                 if (os_strcmp(key, "Type") == 0) {
01224                         if (wpas_dbus_get_scan_type(message, &variant_iter,
01225                                                     &type, &reply) < 0)
01226                                 goto out;
01227                 } else if (os_strcmp(key, "SSIDs") == 0) {
01228                         if (wpas_dbus_get_scan_ssids(message, &variant_iter,
01229                                                      &params, &reply) < 0)
01230                                 goto out;
01231                 } else if (os_strcmp(key, "IEs") == 0) {
01232                         if (wpas_dbus_get_scan_ies(message, &variant_iter,
01233                                                    &params, &reply) < 0)
01234                                 goto out;
01235                 } else if (os_strcmp(key, "Channels") == 0) {
01236                         if (wpas_dbus_get_scan_channels(message, &variant_iter,
01237                                                         &params, &reply) < 0)
01238                                 goto out;
01239                 } else {
01240                         wpa_printf(MSG_DEBUG, "wpas_dbus_handler_scan[dbus]: "
01241                                    "Unknown argument %s", key);
01242                         reply = wpas_dbus_error_invalid_args(message, key);
01243                         goto out;
01244                 }
01245 
01246                 dbus_message_iter_next(&dict_iter);
01247         }
01248 
01249         if (!type) {
01250                 wpa_printf(MSG_DEBUG, "wpas_dbus_handler_scan[dbus]: "
01251                            "Scan type not specified");
01252                 reply = wpas_dbus_error_invalid_args(message, key);
01253                 goto out;
01254         }
01255 
01256         if (!os_strcmp(type, "passive")) {
01257                 if (params.num_ssids || params.extra_ies_len) {
01258                         wpa_printf(MSG_DEBUG, "wpas_dbus_handler_scan[dbus]: "
01259                                    "SSIDs or IEs specified for passive scan.");
01260                         reply = wpas_dbus_error_invalid_args(
01261                                 message, "You can specify only Channels in "
01262                                 "passive scan");
01263                         goto out;
01264                 } else if (params.freqs && params.freqs[0]) {
01265                         /* wildcard ssid */
01266                         params.num_ssids++;
01267                         wpa_supplicant_trigger_scan(wpa_s, &params);
01268                 } else {
01269                         wpa_s->scan_req = 2;
01270                         wpa_supplicant_req_scan(wpa_s, 0, 0);
01271                 }
01272         } else if (!os_strcmp(type, "active")) {
01273                 wpa_supplicant_trigger_scan(wpa_s, &params);
01274         } else {
01275                 wpa_printf(MSG_DEBUG, "wpas_dbus_handler_scan[dbus]: "
01276                            "Unknown scan type: %s", type);
01277                 reply = wpas_dbus_error_invalid_args(message,
01278                                                      "Wrong scan type");
01279                 goto out;
01280         }
01281 
01282 out:
01283         for (i = 0; i < WPAS_MAX_SCAN_SSIDS; i++)
01284                 os_free((u8 *) params.ssids[i].ssid);
01285         os_free((u8 *) params.extra_ies);
01286         os_free(params.freqs);
01287         return reply;
01288 }
01289 
01290 
01291 /*
01292  * wpas_dbus_handler_disconnect - Terminate the current connection
01293  * @message: Pointer to incoming dbus message
01294  * @wpa_s: wpa_supplicant structure for a network interface
01295  * Returns: NotConnected DBus error message if already not connected
01296  * or NULL otherwise.
01297  *
01298  * Handler function for "Disconnect" method call of network interface.
01299  */
01300 DBusMessage * wpas_dbus_handler_disconnect(DBusMessage *message,
01301                                            struct wpa_supplicant *wpa_s)
01302 {
01303         if (wpa_s->current_ssid != NULL) {
01304                 wpa_s->disconnected = 1;
01305                 wpa_supplicant_disassociate(wpa_s, WLAN_REASON_DEAUTH_LEAVING);
01306 
01307                 return NULL;
01308         }
01309 
01310         return dbus_message_new_error(message, WPAS_DBUS_ERROR_NOT_CONNECTED,
01311                                       "This interface is not connected");
01312 }
01313 
01314 
01323 DBusMessage * wpas_dbus_handler_add_network(DBusMessage *message,
01324                                             struct wpa_supplicant *wpa_s)
01325 {
01326         DBusMessage *reply = NULL;
01327         DBusMessageIter iter;
01328         struct wpa_ssid *ssid = NULL;
01329         char path_buf[WPAS_DBUS_OBJECT_PATH_MAX], *path = path_buf;
01330 
01331         dbus_message_iter_init(message, &iter);
01332 
01333         ssid = wpa_config_add_network(wpa_s->conf);
01334         if (ssid == NULL) {
01335                 wpa_printf(MSG_ERROR, "wpas_dbus_handler_add_network[dbus]: "
01336                            "can't add new interface.");
01337                 reply = wpas_dbus_error_unknown_error(
01338                         message,
01339                         "wpa_supplicant could not add "
01340                         "a network on this interface.");
01341                 goto err;
01342         }
01343         wpas_notify_network_added(wpa_s, ssid);
01344         ssid->disabled = 1;
01345         wpa_config_set_network_defaults(ssid);
01346 
01347         reply = set_network_properties(message, wpa_s, ssid, &iter);
01348         if (reply) {
01349                 wpa_printf(MSG_DEBUG, "wpas_dbus_handler_add_network[dbus]:"
01350                            "control interface couldn't set network "
01351                            "properties");
01352                 goto err;
01353         }
01354 
01355         /* Construct the object path for this network. */
01356         os_snprintf(path, WPAS_DBUS_OBJECT_PATH_MAX,
01357                     "%s/" WPAS_DBUS_NEW_NETWORKS_PART "/%d",
01358                     wpa_s->dbus_new_path, ssid->id);
01359 
01360         reply = dbus_message_new_method_return(message);
01361         if (reply == NULL) {
01362                 reply = dbus_message_new_error(message, DBUS_ERROR_NO_MEMORY,
01363                                                NULL);
01364                 goto err;
01365         }
01366         if (!dbus_message_append_args(reply, DBUS_TYPE_OBJECT_PATH, &path,
01367                                       DBUS_TYPE_INVALID)) {
01368                 dbus_message_unref(reply);
01369                 reply = dbus_message_new_error(message, DBUS_ERROR_NO_MEMORY,
01370                                                NULL);
01371                 goto err;
01372         }
01373 
01374         return reply;
01375 
01376 err:
01377         if (ssid) {
01378                 wpas_notify_network_removed(wpa_s, ssid);
01379                 wpa_config_remove_network(wpa_s->conf, ssid->id);
01380         }
01381         return reply;
01382 }
01383 
01384 
01393 DBusMessage * wpas_dbus_handler_remove_network(DBusMessage *message,
01394                                                struct wpa_supplicant *wpa_s)
01395 {
01396         DBusMessage *reply = NULL;
01397         const char *op;
01398         char *iface = NULL, *net_id = NULL;
01399         int id;
01400         struct wpa_ssid *ssid;
01401 
01402         dbus_message_get_args(message, NULL, DBUS_TYPE_OBJECT_PATH, &op,
01403                               DBUS_TYPE_INVALID);
01404 
01405         /* Extract the network ID and ensure the network */
01406         /* is actually a child of this interface */
01407         iface = wpas_dbus_new_decompose_object_path(op, &net_id, NULL);
01408         if (iface == NULL || os_strcmp(iface, wpa_s->dbus_new_path) != 0) {
01409                 reply = wpas_dbus_error_invalid_args(message, op);
01410                 goto out;
01411         }
01412 
01413         id = strtoul(net_id, NULL, 10);
01414         if (errno == EINVAL) {
01415                 reply = wpas_dbus_error_invalid_args(message, op);
01416                 goto out;
01417         }
01418 
01419         ssid = wpa_config_get_network(wpa_s->conf, id);
01420         if (ssid == NULL) {
01421                 reply = wpas_dbus_error_network_unknown(message);
01422                 goto out;
01423         }
01424 
01425         wpas_notify_network_removed(wpa_s, ssid);
01426 
01427         if (wpa_config_remove_network(wpa_s->conf, id) < 0) {
01428                 wpa_printf(MSG_ERROR,
01429                            "wpas_dbus_handler_remove_network[dbus]: "
01430                            "error occurred when removing network %d", id);
01431                 reply = wpas_dbus_error_unknown_error(
01432                         message, "error removing the specified network on "
01433                         "this interface.");
01434                 goto out;
01435         }
01436 
01437         if (ssid == wpa_s->current_ssid)
01438                 wpa_supplicant_disassociate(wpa_s, WLAN_REASON_DEAUTH_LEAVING);
01439 
01440 out:
01441         os_free(iface);
01442         os_free(net_id);
01443         return reply;
01444 }
01445 
01446 
01455 DBusMessage * wpas_dbus_handler_select_network(DBusMessage *message,
01456                                                struct wpa_supplicant *wpa_s)
01457 {
01458         DBusMessage *reply = NULL;
01459         const char *op;
01460         char *iface = NULL, *net_id = NULL;
01461         int id;
01462         struct wpa_ssid *ssid;
01463 
01464         dbus_message_get_args(message, NULL, DBUS_TYPE_OBJECT_PATH, &op,
01465                               DBUS_TYPE_INVALID);
01466 
01467         /* Extract the network ID and ensure the network */
01468         /* is actually a child of this interface */
01469         iface = wpas_dbus_new_decompose_object_path(op, &net_id, NULL);
01470         if (iface == NULL || os_strcmp(iface, wpa_s->dbus_new_path) != 0) {
01471                 reply = wpas_dbus_error_invalid_args(message, op);
01472                 goto out;
01473         }
01474 
01475         id = strtoul(net_id, NULL, 10);
01476         if (errno == EINVAL) {
01477                 reply = wpas_dbus_error_invalid_args(message, op);
01478                 goto out;
01479         }
01480 
01481         ssid = wpa_config_get_network(wpa_s->conf, id);
01482         if (ssid == NULL) {
01483                 reply = wpas_dbus_error_network_unknown(message);
01484                 goto out;
01485         }
01486 
01487         /* Finally, associate with the network */
01488         wpa_supplicant_select_network(wpa_s, ssid);
01489 
01490 out:
01491         os_free(iface);
01492         os_free(net_id);
01493         return reply;
01494 }
01495 
01496 
01505 DBusMessage * wpas_dbus_handler_add_blob(DBusMessage *message,
01506                                          struct wpa_supplicant *wpa_s)
01507 {
01508         DBusMessage *reply = NULL;
01509         DBusMessageIter iter, array_iter;
01510 
01511         char *blob_name;
01512         u8 *blob_data;
01513         int blob_len;
01514         struct wpa_config_blob *blob = NULL;
01515 
01516         dbus_message_iter_init(message, &iter);
01517         dbus_message_iter_get_basic(&iter, &blob_name);
01518 
01519         if (wpa_config_get_blob(wpa_s->conf, blob_name)) {
01520                 return dbus_message_new_error(message,
01521                                               WPAS_DBUS_ERROR_BLOB_EXISTS,
01522                                               NULL);
01523         }
01524 
01525         dbus_message_iter_next(&iter);
01526         dbus_message_iter_recurse(&iter, &array_iter);
01527 
01528         dbus_message_iter_get_fixed_array(&array_iter, &blob_data, &blob_len);
01529 
01530         blob = os_zalloc(sizeof(*blob));
01531         if (!blob) {
01532                 reply = dbus_message_new_error(message, DBUS_ERROR_NO_MEMORY,
01533                                                NULL);
01534                 goto err;
01535         }
01536 
01537         blob->data = os_malloc(blob_len);
01538         if (!blob->data) {
01539                 reply = dbus_message_new_error(message, DBUS_ERROR_NO_MEMORY,
01540                                                NULL);
01541                 goto err;
01542         }
01543         os_memcpy(blob->data, blob_data, blob_len);
01544 
01545         blob->len = blob_len;
01546         blob->name = os_strdup(blob_name);
01547         if (!blob->name) {
01548                 reply = dbus_message_new_error(message, DBUS_ERROR_NO_MEMORY,
01549                                                NULL);
01550                 goto err;
01551         }
01552 
01553         wpa_config_set_blob(wpa_s->conf, blob);
01554         wpas_notify_blob_added(wpa_s, blob->name);
01555 
01556         return reply;
01557 
01558 err:
01559         if (blob) {
01560                 os_free(blob->name);
01561                 os_free(blob->data);
01562                 os_free(blob);
01563         }
01564         return reply;
01565 }
01566 
01567 
01576 DBusMessage * wpas_dbus_handler_get_blob(DBusMessage *message,
01577                                          struct wpa_supplicant *wpa_s)
01578 {
01579         DBusMessage *reply = NULL;
01580         DBusMessageIter iter, array_iter;
01581 
01582         char *blob_name;
01583         const struct wpa_config_blob *blob;
01584 
01585         dbus_message_get_args(message, NULL, DBUS_TYPE_STRING, &blob_name,
01586                               DBUS_TYPE_INVALID);
01587 
01588         blob = wpa_config_get_blob(wpa_s->conf, blob_name);
01589         if (!blob) {
01590                 return dbus_message_new_error(message,
01591                                               WPAS_DBUS_ERROR_BLOB_UNKNOWN,
01592                                               "Blob id not set");
01593         }
01594 
01595         reply = dbus_message_new_method_return(message);
01596         if (!reply) {
01597                 reply = dbus_message_new_error(message, DBUS_ERROR_NO_MEMORY,
01598                                                NULL);
01599                 goto out;
01600         }
01601 
01602         dbus_message_iter_init_append(reply, &iter);
01603 
01604         if (!dbus_message_iter_open_container(&iter, DBUS_TYPE_ARRAY,
01605                                               DBUS_TYPE_BYTE_AS_STRING,
01606                                               &array_iter)) {
01607                 dbus_message_unref(reply);
01608                 reply = dbus_message_new_error(message, DBUS_ERROR_NO_MEMORY,
01609                                                NULL);
01610                 goto out;
01611         }
01612 
01613         if (!dbus_message_iter_append_fixed_array(&array_iter, DBUS_TYPE_BYTE,
01614                                                   &(blob->data), blob->len)) {
01615                 dbus_message_unref(reply);
01616                 reply = dbus_message_new_error(message, DBUS_ERROR_NO_MEMORY,
01617                                                NULL);
01618                 goto out;
01619         }
01620 
01621         if (!dbus_message_iter_close_container(&iter, &array_iter)) {
01622                 dbus_message_unref(reply);
01623                 reply = dbus_message_new_error(message, DBUS_ERROR_NO_MEMORY,
01624                                                NULL);
01625                 goto out;
01626         }
01627 
01628 out:
01629         return reply;
01630 }
01631 
01632 
01641 DBusMessage * wpas_dbus_handler_remove_blob(DBusMessage *message,
01642                                             struct wpa_supplicant *wpa_s)
01643 {
01644         DBusMessage *reply = NULL;
01645         char *blob_name;
01646 
01647         dbus_message_get_args(message, NULL, DBUS_TYPE_STRING, &blob_name,
01648                               DBUS_TYPE_INVALID);
01649 
01650         if (wpa_config_remove_blob(wpa_s->conf, blob_name)) {
01651                 return dbus_message_new_error(message,
01652                                               WPAS_DBUS_ERROR_BLOB_UNKNOWN,
01653                                               "Blob id not set");
01654         }
01655         wpas_notify_blob_removed(wpa_s, blob_name);
01656 
01657         return reply;
01658 
01659 }
01660 
01661 
01670 DBusMessage * wpas_dbus_getter_capabilities(DBusMessage *message,
01671                                             struct wpa_supplicant *wpa_s)
01672 {
01673         DBusMessage *reply = NULL;
01674         struct wpa_driver_capa capa;
01675         int res;
01676         DBusMessageIter iter, iter_dict;
01677         DBusMessageIter iter_dict_entry, iter_dict_val, iter_array,
01678                 variant_iter;
01679         const char *scans[] = { "active", "passive", "ssid" };
01680         const char *modes[] = { "infrastructure", "ad-hoc", "ap" };
01681         int n = sizeof(modes) / sizeof(char *);
01682 
01683         if (message == NULL)
01684                 reply = dbus_message_new(DBUS_MESSAGE_TYPE_SIGNAL);
01685         else
01686                 reply = dbus_message_new_method_return(message);
01687         if (!reply)
01688                 goto nomem;
01689 
01690         dbus_message_iter_init_append(reply, &iter);
01691         if (!dbus_message_iter_open_container(&iter, DBUS_TYPE_VARIANT,
01692                                               "a{sv}", &variant_iter))
01693                 goto nomem;
01694 
01695         if (!wpa_dbus_dict_open_write(&variant_iter, &iter_dict))
01696                 goto nomem;
01697 
01698         res = wpa_drv_get_capa(wpa_s, &capa);
01699 
01700         /***** pairwise cipher */
01701         if (res < 0) {
01702                 const char *args[] = {"ccmp", "tkip", "none"};
01703                 if (!wpa_dbus_dict_append_string_array(
01704                             &iter_dict, "Pairwise", args,
01705                             sizeof(args) / sizeof(char*)))
01706                         goto nomem;
01707         } else {
01708                 if (!wpa_dbus_dict_begin_string_array(&iter_dict, "Pairwise",
01709                                                       &iter_dict_entry,
01710                                                       &iter_dict_val,
01711                                                       &iter_array))
01712                         goto nomem;
01713 
01714                 if (capa.enc & WPA_DRIVER_CAPA_ENC_CCMP) {
01715                         if (!wpa_dbus_dict_string_array_add_element(
01716                                     &iter_array, "ccmp"))
01717                                 goto nomem;
01718                 }
01719 
01720                 if (capa.enc & WPA_DRIVER_CAPA_ENC_TKIP) {
01721                         if (!wpa_dbus_dict_string_array_add_element(
01722                                     &iter_array, "tkip"))
01723                                 goto nomem;
01724                 }
01725 
01726                 if (capa.key_mgmt & WPA_DRIVER_CAPA_KEY_MGMT_WPA_NONE) {
01727                         if (!wpa_dbus_dict_string_array_add_element(
01728                                     &iter_array, "none"))
01729                                 goto nomem;
01730                 }
01731 
01732                 if (!wpa_dbus_dict_end_string_array(&iter_dict,
01733                                                     &iter_dict_entry,
01734                                                     &iter_dict_val,
01735                                                     &iter_array))
01736                         goto nomem;
01737         }
01738 
01739         /***** group cipher */
01740         if (res < 0) {
01741                 const char *args[] = {
01742                         "ccmp", "tkip", "wep104", "wep40"
01743                 };
01744                 if (!wpa_dbus_dict_append_string_array(
01745                             &iter_dict, "Group", args,
01746                             sizeof(args) / sizeof(char*)))
01747                         goto nomem;
01748         } else {
01749                 if (!wpa_dbus_dict_begin_string_array(&iter_dict, "Group",
01750                                                       &iter_dict_entry,
01751                                                       &iter_dict_val,
01752                                                       &iter_array))
01753                         goto nomem;
01754 
01755                 if (capa.enc & WPA_DRIVER_CAPA_ENC_CCMP) {
01756                         if (!wpa_dbus_dict_string_array_add_element(
01757                                     &iter_array, "ccmp"))
01758                                 goto nomem;
01759                 }
01760 
01761                 if (capa.enc & WPA_DRIVER_CAPA_ENC_TKIP) {
01762                         if (!wpa_dbus_dict_string_array_add_element(
01763                                     &iter_array, "tkip"))
01764                                 goto nomem;
01765                 }
01766 
01767                 if (capa.enc & WPA_DRIVER_CAPA_ENC_WEP104) {
01768                         if (!wpa_dbus_dict_string_array_add_element(
01769                                     &iter_array, "wep104"))
01770                                 goto nomem;
01771                 }
01772 
01773                 if (capa.enc & WPA_DRIVER_CAPA_ENC_WEP40) {
01774                         if (!wpa_dbus_dict_string_array_add_element(
01775                                     &iter_array, "wep40"))
01776                                 goto nomem;
01777                 }
01778 
01779                 if (!wpa_dbus_dict_end_string_array(&iter_dict,
01780                                                     &iter_dict_entry,
01781                                                     &iter_dict_val,
01782                                                     &iter_array))
01783                         goto nomem;
01784         }
01785 
01786         /***** key management */
01787         if (res < 0) {
01788                 const char *args[] = {
01789                         "wpa-psk", "wpa-eap", "ieee8021x", "wpa-none",
01790 #ifdef CONFIG_WPS
01791                         "wps",
01792 #endif /* CONFIG_WPS */
01793                         "none"
01794                 };
01795                 if (!wpa_dbus_dict_append_string_array(
01796                             &iter_dict, "KeyMgmt", args,
01797                             sizeof(args) / sizeof(char*)))
01798                         goto nomem;
01799         } else {
01800                 if (!wpa_dbus_dict_begin_string_array(&iter_dict, "KeyMgmt",
01801                                                       &iter_dict_entry,
01802                                                       &iter_dict_val,
01803                                                       &iter_array))
01804                         goto nomem;
01805 
01806                 if (!wpa_dbus_dict_string_array_add_element(&iter_array,
01807                                                             "none"))
01808                         goto nomem;
01809 
01810                 if (!wpa_dbus_dict_string_array_add_element(&iter_array,
01811                                                             "ieee8021x"))
01812                         goto nomem;
01813 
01814                 if (capa.key_mgmt & (WPA_DRIVER_CAPA_KEY_MGMT_WPA |
01815                                      WPA_DRIVER_CAPA_KEY_MGMT_WPA2)) {
01816                         if (!wpa_dbus_dict_string_array_add_element(
01817                                     &iter_array, "wpa-eap"))
01818                                 goto nomem;
01819 
01820                         if (capa.key_mgmt & WPA_DRIVER_CAPA_KEY_MGMT_FT)
01821                                 if (!wpa_dbus_dict_string_array_add_element(
01822                                             &iter_array, "wpa-ft-eap"))
01823                                         goto nomem;
01824 
01825 /* TODO: Ensure that driver actually supports sha256 encryption. */
01826 #ifdef CONFIG_IEEE80211W
01827                         if (!wpa_dbus_dict_string_array_add_element(
01828                                     &iter_array, "wpa-eap-sha256"))
01829                                 goto nomem;
01830 #endif /* CONFIG_IEEE80211W */
01831                 }
01832 
01833                 if (capa.key_mgmt & (WPA_DRIVER_CAPA_KEY_MGMT_WPA_PSK |
01834                                      WPA_DRIVER_CAPA_KEY_MGMT_WPA2_PSK)) {
01835                         if (!wpa_dbus_dict_string_array_add_element(
01836                                     &iter_array, "wpa-psk"))
01837                                 goto nomem;
01838 
01839                         if (capa.key_mgmt & WPA_DRIVER_CAPA_KEY_MGMT_FT_PSK)
01840                                 if (!wpa_dbus_dict_string_array_add_element(
01841                                             &iter_array, "wpa-ft-psk"))
01842                                         goto nomem;
01843 
01844 /* TODO: Ensure that driver actually supports sha256 encryption. */
01845 #ifdef CONFIG_IEEE80211W
01846                         if (!wpa_dbus_dict_string_array_add_element(
01847                                     &iter_array, "wpa-psk-sha256"))
01848                                 goto nomem;
01849 #endif /* CONFIG_IEEE80211W */
01850                 }
01851 
01852                 if (capa.key_mgmt & WPA_DRIVER_CAPA_KEY_MGMT_WPA_NONE) {
01853                         if (!wpa_dbus_dict_string_array_add_element(
01854                                     &iter_array, "wpa-none"))
01855                                 goto nomem;
01856                 }
01857 
01858 
01859 #ifdef CONFIG_WPS
01860                 if (!wpa_dbus_dict_string_array_add_element(&iter_array,
01861                                                             "wps"))
01862                         goto nomem;
01863 #endif /* CONFIG_WPS */
01864 
01865                 if (!wpa_dbus_dict_end_string_array(&iter_dict,
01866                                                     &iter_dict_entry,
01867                                                     &iter_dict_val,
01868                                                     &iter_array))
01869                         goto nomem;
01870         }
01871 
01872         /***** WPA protocol */
01873         if (res < 0) {
01874                 const char *args[] = { "rsn", "wpa" };
01875                 if (!wpa_dbus_dict_append_string_array(
01876                             &iter_dict, "Protocol", args,
01877                             sizeof(args) / sizeof(char*)))
01878                         goto nomem;
01879         } else {
01880                 if (!wpa_dbus_dict_begin_string_array(&iter_dict, "Protocol",
01881                                                       &iter_dict_entry,
01882                                                       &iter_dict_val,
01883                                                       &iter_array))
01884                         goto nomem;
01885 
01886                 if (capa.key_mgmt & (WPA_DRIVER_CAPA_KEY_MGMT_WPA2 |
01887                                      WPA_DRIVER_CAPA_KEY_MGMT_WPA2_PSK)) {
01888                         if (!wpa_dbus_dict_string_array_add_element(
01889                                     &iter_array, "rsn"))
01890                                 goto nomem;
01891                 }
01892 
01893                 if (capa.key_mgmt & (WPA_DRIVER_CAPA_KEY_MGMT_WPA |
01894                                      WPA_DRIVER_CAPA_KEY_MGMT_WPA_PSK)) {
01895                         if (!wpa_dbus_dict_string_array_add_element(
01896                                     &iter_array, "wpa"))
01897                                 goto nomem;
01898                 }
01899 
01900                 if (!wpa_dbus_dict_end_string_array(&iter_dict,
01901                                                     &iter_dict_entry,
01902                                                     &iter_dict_val,
01903                                                     &iter_array))
01904                         goto nomem;
01905         }
01906 
01907         /***** auth alg */
01908         if (res < 0) {
01909                 const char *args[] = { "open", "shared", "leap" };
01910                 if (!wpa_dbus_dict_append_string_array(
01911                             &iter_dict, "AuthAlg", args,
01912                             sizeof(args) / sizeof(char*)))
01913                         goto nomem;
01914         } else {
01915                 if (!wpa_dbus_dict_begin_string_array(&iter_dict, "AuthAlg",
01916                                                       &iter_dict_entry,
01917                                                       &iter_dict_val,
01918                                                       &iter_array))
01919                         goto nomem;
01920 
01921                 if (capa.auth & (WPA_DRIVER_AUTH_OPEN)) {
01922                         if (!wpa_dbus_dict_string_array_add_element(
01923                                     &iter_array, "open"))
01924                                 goto nomem;
01925                 }
01926 
01927                 if (capa.auth & (WPA_DRIVER_AUTH_SHARED)) {
01928                         if (!wpa_dbus_dict_string_array_add_element(
01929                                     &iter_array, "shared"))
01930                                 goto nomem;
01931                 }
01932 
01933                 if (capa.auth & (WPA_DRIVER_AUTH_LEAP)) {
01934                         if (!wpa_dbus_dict_string_array_add_element(
01935                                     &iter_array, "leap"))
01936                                 goto nomem;
01937                 }
01938 
01939                 if (!wpa_dbus_dict_end_string_array(&iter_dict,
01940                                                     &iter_dict_entry,
01941                                                     &iter_dict_val,
01942                                                     &iter_array))
01943                         goto nomem;
01944         }
01945 
01946         /***** Scan */
01947         if (!wpa_dbus_dict_append_string_array(&iter_dict, "Scan", scans,
01948                                                sizeof(scans) / sizeof(char *)))
01949                 goto nomem;
01950 
01951         /***** Modes */
01952         if (res < 0 || !(capa.flags & WPA_DRIVER_FLAGS_AP))
01953                 n--; /* exclude ap mode if it is not supported by the driver */
01954         if (!wpa_dbus_dict_append_string_array(&iter_dict, "Modes", modes, n))
01955                 goto nomem;
01956 
01957         if (!wpa_dbus_dict_close_write(&variant_iter, &iter_dict))
01958                 goto nomem;
01959         if (!dbus_message_iter_close_container(&iter, &variant_iter))
01960                 goto nomem;
01961 
01962         return reply;
01963 
01964 nomem:
01965         if (reply)
01966                 dbus_message_unref(reply);
01967 
01968         return dbus_message_new_error(message, DBUS_ERROR_NO_MEMORY, NULL);
01969 }
01970 
01971 
01981 DBusMessage * wpas_dbus_getter_state(DBusMessage *message,
01982                                      struct wpa_supplicant *wpa_s)
01983 {
01984         DBusMessage *reply = NULL;
01985         const char *str_state;
01986         char *state_ls, *tmp;
01987 
01988         str_state = wpa_supplicant_state_txt(wpa_s->wpa_state);
01989 
01990         /* make state string lowercase to fit new DBus API convention
01991          */
01992         state_ls = tmp = os_strdup(str_state);
01993         if (!tmp) {
01994                 return dbus_message_new_error(message, DBUS_ERROR_NO_MEMORY,
01995                                               NULL);
01996         }
01997         while (*tmp) {
01998                 *tmp = tolower(*tmp);
01999                 tmp++;
02000         }
02001 
02002         reply = wpas_dbus_simple_property_getter(message, DBUS_TYPE_STRING,
02003                                                  &state_ls);
02004 
02005         os_free(state_ls);
02006 
02007         return reply;
02008 }
02009 
02010 
02019 DBusMessage * wpas_dbus_getter_scanning(DBusMessage *message,
02020                                         struct wpa_supplicant *wpa_s)
02021 {
02022         dbus_bool_t scanning = wpa_s->scanning ? TRUE : FALSE;
02023         return wpas_dbus_simple_property_getter(message, DBUS_TYPE_BOOLEAN,
02024                                                 &scanning);
02025 }
02026 
02027 
02036 DBusMessage * wpas_dbus_getter_ap_scan(DBusMessage *message,
02037                                        struct wpa_supplicant *wpa_s)
02038 {
02039         dbus_uint32_t ap_scan = wpa_s->conf->ap_scan;
02040         return wpas_dbus_simple_property_getter(message, DBUS_TYPE_UINT32,
02041                                                 &ap_scan);
02042 }
02043 
02044 
02053 DBusMessage * wpas_dbus_setter_ap_scan(DBusMessage *message,
02054                                        struct wpa_supplicant *wpa_s)
02055 {
02056         DBusMessage *reply = NULL;
02057         dbus_uint32_t ap_scan;
02058 
02059         reply = wpas_dbus_simple_property_setter(message, DBUS_TYPE_UINT32,
02060                                                  &ap_scan);
02061         if (reply)
02062                 return reply;
02063 
02064         if (wpa_supplicant_set_ap_scan(wpa_s, ap_scan)) {
02065                 return wpas_dbus_error_invalid_args(
02066                         message, "ap_scan must equal 0, 1 or 2");
02067         }
02068         return NULL;
02069 }
02070 
02071 
02081 DBusMessage * wpas_dbus_getter_ifname(DBusMessage *message,
02082                                       struct wpa_supplicant *wpa_s)
02083 {
02084         const char *ifname = wpa_s->ifname;
02085         return wpas_dbus_simple_property_getter(message, DBUS_TYPE_STRING,
02086                                                 &ifname);
02087 }
02088 
02089 
02099 DBusMessage * wpas_dbus_getter_driver(DBusMessage *message,
02100                                       struct wpa_supplicant *wpa_s)
02101 {
02102         const char *driver;
02103 
02104         if (wpa_s->driver == NULL || wpa_s->driver->name == NULL) {
02105                 wpa_printf(MSG_DEBUG, "wpas_dbus_getter_driver[dbus]: "
02106                            "wpa_s has no driver set");
02107                 return wpas_dbus_error_unknown_error(message, NULL);
02108         }
02109 
02110         driver = wpa_s->driver->name;
02111         return wpas_dbus_simple_property_getter(message, DBUS_TYPE_STRING,
02112                                                 &driver);
02113 }
02114 
02115 
02125 DBusMessage * wpas_dbus_getter_current_bss(DBusMessage *message,
02126                                            struct wpa_supplicant *wpa_s)
02127 {
02128         DBusMessage *reply;
02129         char path_buf[WPAS_DBUS_OBJECT_PATH_MAX], *bss_obj_path = path_buf;
02130 
02131         if (wpa_s->current_bss)
02132                 os_snprintf(bss_obj_path, WPAS_DBUS_OBJECT_PATH_MAX,
02133                             "%s/" WPAS_DBUS_NEW_BSSIDS_PART "/%u",
02134                             wpa_s->dbus_new_path, wpa_s->current_bss->id);
02135         else
02136                 os_snprintf(bss_obj_path, WPAS_DBUS_OBJECT_PATH_MAX, "/");
02137 
02138         reply = wpas_dbus_simple_property_getter(message,
02139                                                  DBUS_TYPE_OBJECT_PATH,
02140                                                  &bss_obj_path);
02141 
02142         return reply;
02143 }
02144 
02145 
02155 DBusMessage * wpas_dbus_getter_current_network(DBusMessage *message,
02156                                                struct wpa_supplicant *wpa_s)
02157 {
02158         DBusMessage *reply;
02159         char path_buf[WPAS_DBUS_OBJECT_PATH_MAX], *net_obj_path = path_buf;
02160 
02161         if (wpa_s->current_ssid)
02162                 os_snprintf(net_obj_path, WPAS_DBUS_OBJECT_PATH_MAX,
02163                             "%s/" WPAS_DBUS_NEW_NETWORKS_PART "/%u",
02164                             wpa_s->dbus_new_path, wpa_s->current_ssid->id);
02165         else
02166                 os_snprintf(net_obj_path, WPAS_DBUS_OBJECT_PATH_MAX, "/");
02167 
02168         reply = wpas_dbus_simple_property_getter(message,
02169                                                  DBUS_TYPE_OBJECT_PATH,
02170                                                  &net_obj_path);
02171 
02172         return reply;
02173 }
02174 
02175 
02185 DBusMessage * wpas_dbus_getter_bridge_ifname(DBusMessage *message,
02186                                              struct wpa_supplicant *wpa_s)
02187 {
02188         const char *bridge_ifname = NULL;
02189 
02190         bridge_ifname = wpa_s->bridge_ifname;
02191         if (bridge_ifname == NULL) {
02192                 wpa_printf(MSG_ERROR, "wpas_dbus_getter_bridge_ifname[dbus]: "
02193                            "wpa_s has no bridge interface name set");
02194                 return wpas_dbus_error_unknown_error(message, NULL);
02195         }
02196 
02197         return wpas_dbus_simple_property_getter(message, DBUS_TYPE_STRING,
02198                                                 &bridge_ifname);
02199 }
02200 
02201 
02211 DBusMessage * wpas_dbus_getter_bsss(DBusMessage *message,
02212                                     struct wpa_supplicant *wpa_s)
02213 {
02214         DBusMessage *reply = NULL;
02215         struct wpa_bss *bss;
02216         char **paths;
02217         unsigned int i = 0;
02218 
02219         paths = os_zalloc(wpa_s->num_bss * sizeof(char *));
02220         if (!paths) {
02221                 return dbus_message_new_error(message, DBUS_ERROR_NO_MEMORY,
02222                                               NULL);
02223         }
02224 
02225         /* Loop through scan results and append each result's object path */
02226         dl_list_for_each(bss, &wpa_s->bss_id, struct wpa_bss, list_id) {
02227                 paths[i] = os_zalloc(WPAS_DBUS_OBJECT_PATH_MAX);
02228                 if (paths[i] == NULL) {
02229                         reply = dbus_message_new_error(message,
02230                                                        DBUS_ERROR_NO_MEMORY,
02231                                                        NULL);
02232                         goto out;
02233                 }
02234                 /* Construct the object path for this BSS. */
02235                 os_snprintf(paths[i++], WPAS_DBUS_OBJECT_PATH_MAX,
02236                             "%s/" WPAS_DBUS_NEW_BSSIDS_PART "/%u",
02237                             wpa_s->dbus_new_path, bss->id);
02238         }
02239 
02240         reply = wpas_dbus_simple_array_property_getter(message,
02241                                                        DBUS_TYPE_OBJECT_PATH,
02242                                                        paths, wpa_s->num_bss);
02243 
02244 out:
02245         while (i)
02246                 os_free(paths[--i]);
02247         os_free(paths);
02248         return reply;
02249 }
02250 
02251 
02261 DBusMessage * wpas_dbus_getter_networks(DBusMessage *message,
02262                                         struct wpa_supplicant *wpa_s)
02263 {
02264         DBusMessage *reply = NULL;
02265         struct wpa_ssid *ssid;
02266         char **paths;
02267         unsigned int i = 0, num = 0;
02268 
02269         if (wpa_s->conf == NULL) {
02270                 wpa_printf(MSG_ERROR, "wpas_dbus_getter_networks[dbus]: "
02271                            "An error occurred getting networks list.");
02272                 return wpas_dbus_error_unknown_error(message, NULL);
02273         }
02274 
02275         for (ssid = wpa_s->conf->ssid; ssid; ssid = ssid->next)
02276                 num++;
02277 
02278         paths = os_zalloc(num * sizeof(char *));
02279         if (!paths) {
02280                 return dbus_message_new_error(message, DBUS_ERROR_NO_MEMORY,
02281                                               NULL);
02282         }
02283 
02284         /* Loop through configured networks and append object path of each */
02285         for (ssid = wpa_s->conf->ssid; ssid; ssid = ssid->next) {
02286                 paths[i] = os_zalloc(WPAS_DBUS_OBJECT_PATH_MAX);
02287                 if (paths[i] == NULL) {
02288                         reply = dbus_message_new_error(message,
02289                                                        DBUS_ERROR_NO_MEMORY,
02290                                                        NULL);
02291                         goto out;
02292                 }
02293 
02294                 /* Construct the object path for this network. */
02295                 os_snprintf(paths[i++], WPAS_DBUS_OBJECT_PATH_MAX,
02296                             "%s/" WPAS_DBUS_NEW_NETWORKS_PART "/%d",
02297                             wpa_s->dbus_new_path, ssid->id);
02298         }
02299 
02300         reply = wpas_dbus_simple_array_property_getter(message,
02301                                                        DBUS_TYPE_OBJECT_PATH,
02302                                                        paths, num);
02303 
02304 out:
02305         while (i)
02306                 os_free(paths[--i]);
02307         os_free(paths);
02308         return reply;
02309 }
02310 
02311 
02320 DBusMessage * wpas_dbus_getter_blobs(DBusMessage *message,
02321                                      struct wpa_supplicant *wpa_s)
02322 {
02323         DBusMessage *reply = NULL;
02324         DBusMessageIter iter, variant_iter, dict_iter, entry_iter, array_iter;
02325         struct wpa_config_blob *blob;
02326 
02327         if (message == NULL)
02328                 reply = dbus_message_new(DBUS_MESSAGE_TYPE_SIGNAL);
02329         else
02330                 reply = dbus_message_new_method_return(message);
02331         if (!reply)
02332                 return dbus_message_new_error(message, DBUS_ERROR_NO_MEMORY,
02333                                               NULL);
02334 
02335         dbus_message_iter_init_append(reply, &iter);
02336 
02337         if (!dbus_message_iter_open_container(&iter, DBUS_TYPE_VARIANT,
02338                                               "a{say}", &variant_iter) ||
02339             !dbus_message_iter_open_container(&variant_iter, DBUS_TYPE_ARRAY,
02340                                               "{say}", &dict_iter)) {
02341                 dbus_message_unref(reply);
02342                 return dbus_message_new_error(message, DBUS_ERROR_NO_MEMORY,
02343                                               NULL);
02344         }
02345 
02346         blob = wpa_s->conf->blobs;
02347         while (blob) {
02348                 if (!dbus_message_iter_open_container(&dict_iter,
02349                                                       DBUS_TYPE_DICT_ENTRY,
02350                                                       NULL, &entry_iter) ||
02351                     !dbus_message_iter_append_basic(&entry_iter,
02352                                                     DBUS_TYPE_STRING,
02353                                                     &(blob->name)) ||
02354                     !dbus_message_iter_open_container(&entry_iter,
02355                                                       DBUS_TYPE_ARRAY,
02356                                                       DBUS_TYPE_BYTE_AS_STRING,
02357                                                       &array_iter) ||
02358                     !dbus_message_iter_append_fixed_array(&array_iter,
02359                                                           DBUS_TYPE_BYTE,
02360                                                           &(blob->data),
02361                                                           blob->len) ||
02362                     !dbus_message_iter_close_container(&entry_iter,
02363                                                        &array_iter) ||
02364                     !dbus_message_iter_close_container(&dict_iter,
02365                                                        &entry_iter)) {
02366                         dbus_message_unref(reply);
02367                         return dbus_message_new_error(message,
02368                                                       DBUS_ERROR_NO_MEMORY,
02369                                                       NULL);
02370                 }
02371 
02372                 blob = blob->next;
02373         }
02374 
02375         if (!dbus_message_iter_close_container(&variant_iter, &dict_iter) ||
02376             !dbus_message_iter_close_container(&iter, &variant_iter)) {
02377                 dbus_message_unref(reply);
02378                 return dbus_message_new_error(message, DBUS_ERROR_NO_MEMORY,
02379                                               NULL);
02380         }
02381 
02382         return reply;
02383 }
02384 
02385 
02394 DBusMessage * wpas_dbus_getter_bss_bssid(DBusMessage *message,
02395                                          struct bss_handler_args *bss)
02396 {
02397         struct wpa_bss *res = wpa_bss_get_id(bss->wpa_s, bss->id);
02398 
02399         if (!res) {
02400                 wpa_printf(MSG_ERROR, "wpas_dbus_getter_bss_bssid[dbus]: no "
02401                            "bss with id %d found", bss->id);
02402                 return NULL;
02403         }
02404 
02405         return wpas_dbus_simple_array_property_getter(message, DBUS_TYPE_BYTE,
02406                                                       res->bssid, ETH_ALEN);
02407 }
02408 
02409 
02418 DBusMessage * wpas_dbus_getter_bss_ssid(DBusMessage *message,
02419                                               struct bss_handler_args *bss)
02420 {
02421         struct wpa_bss *res = wpa_bss_get_id(bss->wpa_s, bss->id);
02422 
02423         if (!res) {
02424                 wpa_printf(MSG_ERROR, "wpas_dbus_getter_bss_ssid[dbus]: no "
02425                            "bss with id %d found", bss->id);
02426                 return NULL;
02427         }
02428 
02429         return wpas_dbus_simple_array_property_getter(message, DBUS_TYPE_BYTE,
02430                                                       res->ssid,
02431                                                       res->ssid_len);
02432 }
02433 
02434 
02443 DBusMessage * wpas_dbus_getter_bss_privacy(DBusMessage *message,
02444                                            struct bss_handler_args *bss)
02445 {
02446         struct wpa_bss *res = wpa_bss_get_id(bss->wpa_s, bss->id);
02447         dbus_bool_t privacy;
02448 
02449         if (!res) {
02450                 wpa_printf(MSG_ERROR, "wpas_dbus_getter_bss_privacy[dbus]: no "
02451                            "bss with id %d found", bss->id);
02452                 return NULL;
02453         }
02454 
02455         privacy = (res->caps & IEEE80211_CAP_PRIVACY) ? TRUE : FALSE;
02456         return wpas_dbus_simple_property_getter(message, DBUS_TYPE_BOOLEAN,
02457                                                 &privacy);
02458 }
02459 
02460 
02469 DBusMessage * wpas_dbus_getter_bss_mode(DBusMessage *message,
02470                                         struct bss_handler_args *bss)
02471 {
02472         struct wpa_bss *res = wpa_bss_get_id(bss->wpa_s, bss->id);
02473         const char *mode;
02474 
02475         if (!res) {
02476                 wpa_printf(MSG_ERROR, "wpas_dbus_getter_bss_mode[dbus]: no "
02477                            "bss with id %d found", bss->id);
02478                 return NULL;
02479         }
02480 
02481         if (res->caps & IEEE80211_CAP_IBSS)
02482                 mode = "ad-hoc";
02483         else
02484                 mode = "infrastructure";
02485 
02486         return wpas_dbus_simple_property_getter(message, DBUS_TYPE_STRING,
02487                                                 &mode);
02488 }
02489 
02490 
02499 DBusMessage * wpas_dbus_getter_bss_signal(DBusMessage *message,
02500                                           struct bss_handler_args *bss)
02501 {
02502         struct wpa_bss *res = wpa_bss_get_id(bss->wpa_s, bss->id);
02503 
02504         if (!res) {
02505                 wpa_printf(MSG_ERROR, "wpas_dbus_getter_bss_signal[dbus]: no "
02506                            "bss with id %d found", bss->id);
02507                 return NULL;
02508         }
02509 
02510         return wpas_dbus_simple_property_getter(message, DBUS_TYPE_INT16,
02511                                                 &res->level);
02512 }
02513 
02514 
02523 DBusMessage * wpas_dbus_getter_bss_frequency(DBusMessage *message,
02524                                              struct bss_handler_args *bss)
02525 {
02526         struct wpa_bss *res = wpa_bss_get_id(bss->wpa_s, bss->id);
02527 
02528         if (!res) {
02529                 wpa_printf(MSG_ERROR, "wpas_dbus_getter_bss_frequency[dbus]: "
02530                            "no bss with id %d found", bss->id);
02531                 return NULL;
02532         }
02533 
02534         return wpas_dbus_simple_property_getter(message, DBUS_TYPE_UINT16,
02535                                                 &res->freq);
02536 }
02537 
02538 
02539 static int cmp_u8s_desc(const void *a, const void *b)
02540 {
02541         return (*(u8 *) b - *(u8 *) a);
02542 }
02543 
02544 
02553 DBusMessage * wpas_dbus_getter_bss_rates(DBusMessage *message,
02554                                             struct bss_handler_args *bss)
02555 {
02556         DBusMessage *reply;
02557         struct wpa_bss *res = wpa_bss_get_id(bss->wpa_s, bss->id);
02558         u8 *ie_rates = NULL;
02559         u32 *real_rates;
02560         int rates_num, i;
02561 
02562         if (!res) {
02563                 wpa_printf(MSG_ERROR, "wpas_dbus_getter_bss_rates[dbus]: "
02564                            "no bss with id %d found", bss->id);
02565                 return NULL;
02566         }
02567 
02568         rates_num = wpa_bss_get_bit_rates(res, &ie_rates);
02569         if (rates_num < 0)
02570                 return NULL;
02571 
02572         qsort(ie_rates, rates_num, 1, cmp_u8s_desc);
02573 
02574         real_rates = os_malloc(sizeof(u32) * rates_num);
02575         if (!real_rates) {
02576                 os_free(ie_rates);
02577                 return dbus_message_new_error(message, DBUS_ERROR_NO_MEMORY,
02578                                               NULL);
02579         }
02580 
02581         for (i = 0; i < rates_num; i++)
02582                 real_rates[i] = ie_rates[i] * 500000;
02583 
02584         reply = wpas_dbus_simple_array_property_getter(message,
02585                                                        DBUS_TYPE_UINT32,
02586                                                        real_rates, rates_num);
02587 
02588         os_free(ie_rates);
02589         os_free(real_rates);
02590         return reply;
02591 }
02592 
02593 
02594 static DBusMessage * wpas_dbus_get_bss_security_prop(
02595         DBusMessage *message, struct wpa_ie_data *ie_data)
02596 {
02597         DBusMessage *reply;
02598         DBusMessageIter iter, iter_dict, variant_iter;
02599         const char *group;
02600         const char *pairwise[2]; /* max 2 pairwise ciphers is supported */
02601         const char *key_mgmt[7]; /* max 7 key managements may be supported */
02602         int n;
02603 
02604         if (message == NULL)
02605                 reply = dbus_message_new(DBUS_MESSAGE_TYPE_SIGNAL);
02606         else
02607                 reply = dbus_message_new_method_return(message);
02608         if (!reply)
02609                 goto nomem;
02610 
02611         dbus_message_iter_init_append(reply, &iter);
02612         if (!dbus_message_iter_open_container(&iter, DBUS_TYPE_VARIANT,
02613                                               "a{sv}", &variant_iter))
02614                 goto nomem;
02615 
02616         if (!wpa_dbus_dict_open_write(&variant_iter, &iter_dict))
02617                 goto nomem;
02618 
02619         /* KeyMgmt */
02620         n = 0;
02621         if (ie_data->key_mgmt & WPA_KEY_MGMT_PSK)
02622                 key_mgmt[n++] = "wpa-psk";
02623         if (ie_data->key_mgmt & WPA_KEY_MGMT_FT_PSK)
02624                 key_mgmt[n++] = "wpa-ft-psk";
02625         if (ie_data->key_mgmt & WPA_KEY_MGMT_PSK_SHA256)
02626                 key_mgmt[n++] = "wpa-psk-sha256";
02627         if (ie_data->key_mgmt & WPA_KEY_MGMT_IEEE8021X)
02628                 key_mgmt[n++] = "wpa-eap";
02629         if (ie_data->key_mgmt & WPA_KEY_MGMT_FT_IEEE8021X)
02630                 key_mgmt[n++] = "wpa-ft-eap";
02631         if (ie_data->key_mgmt & WPA_KEY_MGMT_IEEE8021X_SHA256)
02632                 key_mgmt[n++] = "wpa-eap-sha256";
02633         if (ie_data->key_mgmt & WPA_KEY_MGMT_NONE)
02634                 key_mgmt[n++] = "wpa-none";
02635 
02636         if (!wpa_dbus_dict_append_string_array(&iter_dict, "KeyMgmt",
02637                                                key_mgmt, n))
02638                 goto nomem;
02639 
02640         /* Group */
02641         switch (ie_data->group_cipher) {
02642         case WPA_CIPHER_WEP40:
02643                 group = "wep40";
02644                 break;
02645         case WPA_CIPHER_TKIP:
02646                 group = "tkip";
02647                 break;
02648         case WPA_CIPHER_CCMP:
02649                 group = "ccmp";
02650                 break;
02651         case WPA_CIPHER_WEP104:
02652                 group = "wep104";
02653                 break;
02654         default:
02655                 group = "";
02656                 break;
02657         }
02658 
02659         if (!wpa_dbus_dict_append_string(&iter_dict, "Group", group))
02660                 goto nomem;
02661 
02662         /* Pairwise */
02663         n = 0;
02664         if (ie_data->pairwise_cipher & WPA_CIPHER_TKIP)
02665                 pairwise[n++] = "tkip";
02666         if (ie_data->pairwise_cipher & WPA_CIPHER_CCMP)
02667                 pairwise[n++] = "ccmp";
02668 
02669         if (!wpa_dbus_dict_append_string_array(&iter_dict, "Pairwise",
02670                                                pairwise, n))
02671                 goto nomem;
02672 
02673         /* Management group (RSN only) */
02674         if (ie_data->proto == WPA_PROTO_RSN) {
02675                 switch (ie_data->mgmt_group_cipher) {
02676 #ifdef CONFIG_IEEE80211W
02677                 case WPA_CIPHER_AES_128_CMAC:
02678                         group = "aes128cmac";
02679                         break;
02680 #endif /* CONFIG_IEEE80211W */
02681                 default:
02682                         group = "";
02683                         break;
02684                 }
02685 
02686                 if (!wpa_dbus_dict_append_string(&iter_dict, "MgmtGroup",
02687                                                  group))
02688                         goto nomem;
02689         }
02690 
02691         if (!wpa_dbus_dict_close_write(&variant_iter, &iter_dict))
02692                 goto nomem;
02693         if (!dbus_message_iter_close_container(&iter, &variant_iter))
02694                 goto nomem;
02695 
02696         return reply;
02697 
02698 nomem:
02699         if (reply)
02700                 dbus_message_unref(reply);
02701 
02702         return dbus_message_new_error(message, DBUS_ERROR_NO_MEMORY, NULL);
02703 }
02704 
02705 
02714 DBusMessage * wpas_dbus_getter_bss_wpa(DBusMessage *message,
02715                                        struct bss_handler_args *bss)
02716 {
02717         struct wpa_bss *res = wpa_bss_get_id(bss->wpa_s, bss->id);
02718         struct wpa_ie_data wpa_data;
02719         const u8 *ie;
02720 
02721         if (!res) {
02722                 wpa_printf(MSG_ERROR, "wpas_dbus_getter_bss_wpa[dbus]: no "
02723                            "bss with id %d found", bss->id);
02724                 return NULL;
02725         }
02726 
02727         os_memset(&wpa_data, 0, sizeof(wpa_data));
02728         ie = wpa_bss_get_vendor_ie(res, WPA_IE_VENDOR_TYPE);
02729         if (ie)
02730                 wpa_parse_wpa_ie(ie, 2 + ie[1], &wpa_data);
02731 
02732         return wpas_dbus_get_bss_security_prop(message, &wpa_data);
02733 }
02734 
02735 
02744 DBusMessage * wpas_dbus_getter_bss_rsn(DBusMessage *message,
02745                                        struct bss_handler_args *bss)
02746 {
02747         struct wpa_bss *res = wpa_bss_get_id(bss->wpa_s, bss->id);
02748         struct wpa_ie_data wpa_data;
02749         const u8 *ie;
02750 
02751         if (!res) {
02752                 wpa_printf(MSG_ERROR, "wpas_dbus_getter_bss_rsn[dbus]: no "
02753                            "bss with id %d found", bss->id);
02754                 return NULL;
02755         }
02756 
02757         os_memset(&wpa_data, 0, sizeof(wpa_data));
02758         ie = wpa_bss_get_ie(res, WLAN_EID_RSN);
02759         if (ie)
02760                 wpa_parse_wpa_ie(ie, 2 + ie[1], &wpa_data);
02761 
02762         return wpas_dbus_get_bss_security_prop(message, &wpa_data);
02763 }
02764 
02765 
02774 DBusMessage * wpas_dbus_getter_bss_ies(DBusMessage *message,
02775                                        struct bss_handler_args *bss)
02776 {
02777         struct wpa_bss *res = wpa_bss_get_id(bss->wpa_s, bss->id);
02778 
02779         if (!res) {
02780                 wpa_printf(MSG_ERROR, "wpas_dbus_getter_bss_ies[dbus]: no "
02781                            "bss with id %d found", bss->id);
02782                 return NULL;
02783         }
02784 
02785         return wpas_dbus_simple_array_property_getter(message, DBUS_TYPE_BYTE,
02786                                                       res + 1, res->ie_len);
02787 }
02788 
02789 
02800 DBusMessage * wpas_dbus_getter_enabled(DBusMessage *message,
02801                                        struct network_handler_args *net)
02802 {
02803         dbus_bool_t enabled = net->ssid->disabled ? FALSE : TRUE;
02804         return wpas_dbus_simple_property_getter(message, DBUS_TYPE_BOOLEAN,
02805                                                 &enabled);
02806 }
02807 
02808 
02818 DBusMessage * wpas_dbus_setter_enabled(DBusMessage *message,
02819                                        struct network_handler_args *net)
02820 {
02821         DBusMessage *reply = NULL;
02822 
02823         struct wpa_supplicant *wpa_s;
02824         struct wpa_ssid *ssid;
02825 
02826         dbus_bool_t enable;
02827 
02828         reply = wpas_dbus_simple_property_setter(message, DBUS_TYPE_BOOLEAN,
02829                                                  &enable);
02830 
02831         if (reply)
02832                 return reply;
02833 
02834         wpa_s = net->wpa_s;
02835         ssid = net->ssid;
02836 
02837         if (enable)
02838                 wpa_supplicant_enable_network(wpa_s, ssid);
02839         else
02840                 wpa_supplicant_disable_network(wpa_s, ssid);
02841 
02842         return NULL;
02843 }
02844 
02845 
02855 DBusMessage * wpas_dbus_getter_network_properties(
02856         DBusMessage *message, struct network_handler_args *net)
02857 {
02858         DBusMessage *reply = NULL;
02859         DBusMessageIter iter, variant_iter, dict_iter;
02860         char **iterator;
02861         char **props = wpa_config_get_all(net->ssid, 1);
02862         if (!props)
02863                 return dbus_message_new_error(message, DBUS_ERROR_NO_MEMORY,
02864                                               NULL);
02865 
02866         if (message == NULL)
02867                 reply = dbus_message_new(DBUS_MESSAGE_TYPE_SIGNAL);
02868         else
02869                 reply = dbus_message_new_method_return(message);
02870         if (!reply) {
02871                 reply = dbus_message_new_error(message, DBUS_ERROR_NO_MEMORY,
02872                                                NULL);
02873                 goto out;
02874         }
02875 
02876         dbus_message_iter_init_append(reply, &iter);
02877 
02878         if (!dbus_message_iter_open_container(&iter, DBUS_TYPE_VARIANT,
02879                         "a{sv}", &variant_iter) ||
02880             !wpa_dbus_dict_open_write(&variant_iter, &dict_iter)) {
02881                 dbus_message_unref(reply);
02882                 reply = dbus_message_new_error(message, DBUS_ERROR_NO_MEMORY,
02883                                                NULL);
02884                 goto out;
02885         }
02886 
02887         iterator = props;
02888         while (*iterator) {
02889                 if (!wpa_dbus_dict_append_string(&dict_iter, *iterator,
02890                                                  *(iterator + 1))) {
02891                         dbus_message_unref(reply);
02892                         reply = dbus_message_new_error(message,
02893                                                        DBUS_ERROR_NO_MEMORY,
02894                                                        NULL);
02895                         goto out;
02896                 }
02897                 iterator += 2;
02898         }
02899 
02900 
02901         if (!wpa_dbus_dict_close_write(&variant_iter, &dict_iter) ||
02902             !dbus_message_iter_close_container(&iter, &variant_iter)) {
02903                 dbus_message_unref(reply);
02904                 reply = dbus_message_new_error(message, DBUS_ERROR_NO_MEMORY,
02905                                                NULL);
02906                 goto out;
02907         }
02908 
02909 out:
02910         iterator = props;
02911         while (*iterator) {
02912                 os_free(*iterator);
02913                 iterator++;
02914         }
02915         os_free(props);
02916         return reply;
02917 }
02918 
02919 
02929 DBusMessage * wpas_dbus_setter_network_properties(
02930         DBusMessage *message, struct network_handler_args *net)
02931 {
02932         struct wpa_ssid *ssid = net->ssid;
02933 
02934         DBusMessage *reply = NULL;
02935         DBusMessageIter iter, variant_iter;
02936 
02937         dbus_message_iter_init(message, &iter);
02938 
02939         dbus_message_iter_next(&iter);
02940         dbus_message_iter_next(&iter);
02941 
02942         dbus_message_iter_recurse(&iter, &variant_iter);
02943 
02944         reply = set_network_properties(message, net->wpa_s, ssid,
02945                                        &variant_iter);
02946        
02947         if (reply)
02948                 wpa_printf(MSG_DEBUG, "dbus control interface couldn't set "
02949                            "network properties");
02950 
02951         ros_network_list_updated(net->wpa_s);
02952 
02953         return reply;
02954 }


wpa_supplicant_node
Author(s): Package maintained by Blaise Gassend
autogenerated on Thu Jan 2 2014 11:25:12