From ccd286d0259d1569e9bec4b9bd6ad042e2397aec Mon Sep 17 00:00:00 2001 From: Jouni Malinen Date: Mon, 28 Dec 2009 01:10:07 +0200 Subject: [PATCH] dbus: Use the new BSS table with the new D-Bus API Replace the scan results -based implementation with the use of information from the new BSS table maintained by wpa_supplicant to get a more stable source of BSS data. Change the use of BSSID as the key for the BSS object to use the BSS table unique identifier so that multi-SSID APs can be handled properly. --- wpa_supplicant/dbus/dbus_new.c | 27 +++++----- wpa_supplicant/dbus/dbus_new.h | 7 ++- wpa_supplicant/dbus/dbus_new_handlers.c | 71 +++++++------------------ wpa_supplicant/dbus/dbus_new_handlers.h | 2 +- wpa_supplicant/notify.c | 4 +- 5 files changed, 40 insertions(+), 71 deletions(-) diff --git a/wpa_supplicant/dbus/dbus_new.c b/wpa_supplicant/dbus/dbus_new.c index 6085d5863..f94d818c1 100644 --- a/wpa_supplicant/dbus/dbus_new.c +++ b/wpa_supplicant/dbus/dbus_new.c @@ -2,6 +2,7 @@ * WPA Supplicant / dbus-based control interface * Copyright (c) 2006, Dan Williams and Red Hat, Inc. * Copyright (c) 2009, Witold Sowa + * Copyright (c) 2009, Jouni Malinen * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 as @@ -16,10 +17,10 @@ #include "includes.h" #include "common.h" -#include "drivers/driver.h" #include "wps/wps.h" #include "../config.h" #include "../wpa_supplicant_i.h" +#include "../bss.h" #include "dbus_new_helpers.h" #include "dbus_dict_helpers.h" #include "dbus_new.h" @@ -1242,12 +1243,13 @@ static int wpas_dbus_unregister_network(struct wpa_supplicant *wpa_s, int nid) * wpas_dbus_unregister_bss - Unregister a scanned BSS from dbus * @wpa_s: wpa_supplicant interface structure * @bssid: scanned network bssid + * @id: unique BSS identifier * Returns: 0 on success, -1 on failure * * Unregisters BSS representing object from dbus */ static int wpas_dbus_unregister_bss(struct wpa_supplicant *wpa_s, - u8 bssid[ETH_ALEN]) + u8 bssid[ETH_ALEN], unsigned int id) { struct ctrl_iface_dbus_new_priv *ctrl_iface; char *bss_obj_path; @@ -1264,8 +1266,8 @@ static int wpas_dbus_unregister_bss(struct wpa_supplicant *wpa_s, return -1; os_snprintf(bss_obj_path, WPAS_DBUS_OBJECT_PATH_MAX, - "%s/" WPAS_DBUS_NEW_BSSIDS_PART "/" WPAS_DBUS_BSSID_FORMAT, - wpas_dbus_get_path(wpa_s), MAC2STR(bssid)); + "%s/" WPAS_DBUS_NEW_BSSIDS_PART "/%u", + wpas_dbus_get_path(wpa_s), id); if (wpa_dbus_unregister_object_per_iface(ctrl_iface, bss_obj_path)) { wpa_printf(MSG_ERROR, @@ -1286,12 +1288,13 @@ static int wpas_dbus_unregister_bss(struct wpa_supplicant *wpa_s, * wpas_dbus_register_bss - Register a scanned BSS with dbus * @wpa_s: wpa_supplicant interface structure * @bssid: scanned network bssid + * @id: unique BSS identifier * Returns: 0 on success, -1 on failure * * Registers BSS representing object with dbus */ static int wpas_dbus_register_bss(struct wpa_supplicant *wpa_s, - u8 bssid[ETH_ALEN]) + u8 bssid[ETH_ALEN], unsigned int id) { struct ctrl_iface_dbus_new_priv *ctrl_iface; struct wpa_dbus_object_desc *obj_desc; @@ -1311,8 +1314,8 @@ static int wpas_dbus_register_bss(struct wpa_supplicant *wpa_s, return -1; os_snprintf(bss_obj_path, WPAS_DBUS_OBJECT_PATH_MAX, - "%s/" WPAS_DBUS_NEW_BSSIDS_PART "/" WPAS_DBUS_BSSID_FORMAT, - wpas_dbus_get_path(wpa_s), MAC2STR(bssid)); + "%s/" WPAS_DBUS_NEW_BSSIDS_PART "/%u", + wpas_dbus_get_path(wpa_s), id); obj_desc = os_zalloc(sizeof(struct wpa_dbus_object_desc)); if (!obj_desc) { @@ -1328,7 +1331,7 @@ static int wpas_dbus_register_bss(struct wpa_supplicant *wpa_s, goto err; } arg->wpa_s = wpa_s; - os_memcpy(arg->bssid, bssid, ETH_ALEN); + arg->id = id; /* Properties property */ wpa_dbus_property_register(obj_desc, WPAS_DBUS_NEW_IFACE_BSSID, @@ -1636,7 +1639,7 @@ static int wpas_dbus_unregister_interface(struct wpa_supplicant *wpa_s) { struct ctrl_iface_dbus_new_priv *ctrl_iface; struct wpa_ssid *ssid; - size_t i; + struct wpa_bss *bss; /* Do nothing if the control interface is not turned on */ if (wpa_s == NULL || wpa_s->global == NULL) @@ -1646,10 +1649,8 @@ static int wpas_dbus_unregister_interface(struct wpa_supplicant *wpa_s) return 0; /* unregister all BSSs and networks from dbus */ - for (i = 0; wpa_s->scan_res && i < wpa_s->scan_res->num; i++) { - wpas_dbus_unregister_bss(wpa_s, - wpa_s->scan_res->res[i]->bssid); - } + dl_list_for_each(bss, &wpa_s->bss, struct wpa_bss, list) + wpas_dbus_unregister_bss(wpa_s, bss->bssid, bss->id); ssid = wpa_s->conf->ssid; while (ssid) { diff --git a/wpa_supplicant/dbus/dbus_new.h b/wpa_supplicant/dbus/dbus_new.h index e26394502..7ec4560a3 100644 --- a/wpa_supplicant/dbus/dbus_new.h +++ b/wpa_supplicant/dbus/dbus_new.h @@ -63,9 +63,10 @@ struct wpas_dbus_callbacks { void (*signal_network_enabled_changed)(struct wpa_supplicant *wpa_s, struct wpa_ssid *ssid); - int (*register_bss)(struct wpa_supplicant *wpa_s, u8 bssid[ETH_ALEN]); + int (*register_bss)(struct wpa_supplicant *wpa_s, u8 bssid[ETH_ALEN], + unsigned int id); int (*unregister_bss)(struct wpa_supplicant *wpa_s, - u8 bssid[ETH_ALEN]); + u8 bssid[ETH_ALEN], unsigned int id); void (*signal_prop_changed)(struct wpa_supplicant *wpa_s, enum wpas_dbus_prop property); @@ -123,8 +124,6 @@ struct wpas_dbus_callbacks { #define WPAS_DBUS_ERROR_BLOB_UNKNOWN \ WPAS_DBUS_NEW_IFACE_INTERFACE ".BlobUnknown" -#define WPAS_DBUS_BSSID_FORMAT "%02x%02x%02x%02x%02x%02x" - struct wpas_dbus_callbacks * wpas_dbus_get_callbacks(void); const char * wpas_dbus_get_path(struct wpa_supplicant *wpa_s); diff --git a/wpa_supplicant/dbus/dbus_new_handlers.c b/wpa_supplicant/dbus/dbus_new_handlers.c index 20ac1ae00..fe763add9 100644 --- a/wpa_supplicant/dbus/dbus_new_handlers.c +++ b/wpa_supplicant/dbus/dbus_new_handlers.c @@ -2,6 +2,7 @@ * WPA Supplicant / dbus-based control interface * Copyright (c) 2006, Dan Williams and Red Hat, Inc. * Copyright (c) 2009, Witold Sowa + * Copyright (c) 2009, Jouni Malinen * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 as @@ -24,6 +25,7 @@ #include "../driver_i.h" #include "../notify.h" #include "../wpas_glue.h" +#include "../bss.h" #include "dbus_new_helpers.h" #include "dbus_new.h" #include "dbus_new_handlers.h" @@ -184,18 +186,6 @@ static dbus_bool_t should_quote_opt(const char *key) return TRUE; } -static struct wpa_scan_res * find_scan_result(struct bss_handler_args *bss) -{ - struct wpa_scan_results *results = bss->wpa_s->scan_res; - size_t i; - for (i = 0; results && i < results->num; i++) { - if (!os_memcmp(results->res[i]->bssid, bss->bssid, ETH_ALEN)) - return results->res[i]; - } - return NULL; -} - - /** * get_iface_by_dbus_path - Get a new network interface * @global: Pointer to global data from wpa_supplicant_init() @@ -2274,7 +2264,7 @@ DBusMessage * wpas_dbus_getter_current_bss(DBusMessage *message, DBusMessageIter iter, variant_iter; const char *path = wpas_dbus_get_path(wpa_s); char *bss_obj_path = os_zalloc(WPAS_DBUS_OBJECT_PATH_MAX); - int is_bssid_known = 0; + struct wpa_bss *bss = NULL; if (bss_obj_path == NULL) { perror("wpas_dbus_getter_current_bss[dbus]: out of " @@ -2283,22 +2273,14 @@ DBusMessage * wpas_dbus_getter_current_bss(DBusMessage *message, NULL); } - if (!is_zero_ether_addr(wpa_s->bssid)) { - size_t i; - for (i = 0; wpa_s->scan_res && i < wpa_s->scan_res->num; i++) { - struct wpa_scan_res *res = wpa_s->scan_res->res[i]; - if (!os_memcmp(wpa_s->bssid, res->bssid, ETH_ALEN)) { - is_bssid_known = 1; - break; - } - } - } + /* TODO: store current BSS or BSS id in wpa_s */ + if (!is_zero_ether_addr(wpa_s->bssid)) + bss = wpa_bss_get_bssid(wpa_s, wpa_s->bssid); - if (is_bssid_known) + if (bss) os_snprintf(bss_obj_path, WPAS_DBUS_OBJECT_PATH_MAX, - "%s/" WPAS_DBUS_NEW_BSSIDS_PART "/" - WPAS_DBUS_BSSID_FORMAT, - path, MAC2STR(wpa_s->bssid)); + "%s/" WPAS_DBUS_NEW_BSSIDS_PART "/%u", + path, bss->id); else os_snprintf(bss_obj_path, WPAS_DBUS_OBJECT_PATH_MAX, "/"); @@ -2465,15 +2447,7 @@ DBusMessage * wpas_dbus_getter_bsss(DBusMessage *message, { DBusMessage *reply = NULL; DBusMessageIter iter, variant_iter, array_iter; - size_t i; - - /* Ensure we've actually got scan results to return */ - if (wpa_s->scan_res == NULL && - wpa_supplicant_get_scan_results(wpa_s) < 0) { - wpa_printf(MSG_ERROR, "wpas_dbus_getter_bsss[dbus]: " - "An error occurred getting scan results."); - return wpas_dbus_error_unknown_error(message, NULL); - } + struct wpa_bss *bss; /* Create and initialize the return message */ if (message == NULL) @@ -2504,8 +2478,7 @@ DBusMessage * wpas_dbus_getter_bsss(DBusMessage *message, } /* Loop through scan results and append each result's object path */ - for (i = 0; i < wpa_s->scan_res->num; i++) { - struct wpa_scan_res *res = wpa_s->scan_res->res[i]; + dl_list_for_each(bss, &wpa_s->bss_id, struct wpa_bss, list_id) { char *path; path = os_zalloc(WPAS_DBUS_OBJECT_PATH_MAX); @@ -2518,14 +2491,10 @@ DBusMessage * wpas_dbus_getter_bsss(DBusMessage *message, NULL); goto out; } - /* Construct the object path for this BSS. Note that ':' - * is not a valid character in dbus object paths. - */ + /* Construct the object path for this BSS. */ os_snprintf(path, WPAS_DBUS_OBJECT_PATH_MAX, - "%s/" WPAS_DBUS_NEW_BSSIDS_PART "/" - WPAS_DBUS_BSSID_FORMAT, - wpas_dbus_get_path(wpa_s), - MAC2STR(res->bssid)); + "%s/" WPAS_DBUS_NEW_BSSIDS_PART "/%u", + wpas_dbus_get_path(wpa_s), bss->id); dbus_message_iter_append_basic(&array_iter, DBUS_TYPE_OBJECT_PATH, &path); os_free(path); @@ -2798,7 +2767,7 @@ DBusMessage * wpas_dbus_getter_bss_properties(DBusMessage *message, DBusMessage *reply = NULL; DBusMessageIter iter, iter_dict, variant_iter; const u8 *ie; - struct wpa_scan_res *res = find_scan_result(bss); + struct wpa_bss *res = wpa_bss_get_id(bss->wpa_s, bss->id); if (res == NULL) return NULL; @@ -2826,7 +2795,7 @@ DBusMessage * wpas_dbus_getter_bss_properties(DBusMessage *message, ETH_ALEN)) goto error; - ie = wpa_scan_get_ie(res, WLAN_EID_SSID); + ie = wpa_bss_get_ie(res, WLAN_EID_SSID); if (ie) { if (!wpa_dbus_dict_append_byte_array(&iter_dict, "SSID", (const char *) (ie + 2), @@ -2834,7 +2803,7 @@ DBusMessage * wpas_dbus_getter_bss_properties(DBusMessage *message, goto error; } - ie = wpa_scan_get_vendor_ie(res, WPA_IE_VENDOR_TYPE); + ie = wpa_bss_get_vendor_ie(res, WPA_IE_VENDOR_TYPE); if (ie) { if (!wpa_dbus_dict_append_byte_array(&iter_dict, "WPAIE", (const char *) ie, @@ -2842,7 +2811,7 @@ DBusMessage * wpas_dbus_getter_bss_properties(DBusMessage *message, goto error; } - ie = wpa_scan_get_ie(res, WLAN_EID_RSN); + ie = wpa_bss_get_ie(res, WLAN_EID_RSN); if (ie) { if (!wpa_dbus_dict_append_byte_array(&iter_dict, "RSNIE", (const char *) ie, @@ -2850,7 +2819,7 @@ DBusMessage * wpas_dbus_getter_bss_properties(DBusMessage *message, goto error; } - ie = wpa_scan_get_vendor_ie(res, WPS_IE_VENDOR_TYPE); + ie = wpa_bss_get_vendor_ie(res, WPS_IE_VENDOR_TYPE); if (ie) { if (!wpa_dbus_dict_append_byte_array(&iter_dict, "WPSIE", (const char *) ie, @@ -2876,7 +2845,7 @@ DBusMessage * wpas_dbus_getter_bss_properties(DBusMessage *message, !wpa_dbus_dict_append_int32(&iter_dict, "Level", res->level)) goto error; if (!wpa_dbus_dict_append_int32(&iter_dict, "MaxRate", - wpa_scan_get_max_rate(res) * 500000)) + wpa_bss_get_max_rate(res) * 500000)) goto error; if (!wpa_dbus_dict_close_write(&iter, &iter_dict)) diff --git a/wpa_supplicant/dbus/dbus_new_handlers.h b/wpa_supplicant/dbus/dbus_new_handlers.h index f21a15b1b..6a8a21d02 100644 --- a/wpa_supplicant/dbus/dbus_new_handlers.h +++ b/wpa_supplicant/dbus/dbus_new_handlers.h @@ -22,7 +22,7 @@ struct network_handler_args { struct bss_handler_args { struct wpa_supplicant *wpa_s; - u8 bssid[ETH_ALEN]; + unsigned int id; }; DBusMessage * wpas_dbus_handler_create_interface(DBusMessage *message, diff --git a/wpa_supplicant/notify.c b/wpa_supplicant/notify.c index 6c2f44704..03f752127 100644 --- a/wpa_supplicant/notify.c +++ b/wpa_supplicant/notify.c @@ -244,7 +244,7 @@ void wpas_notify_bss_added(struct wpa_supplicant *wpa_s, { struct wpas_dbus_callbacks *cbs = wpas_dbus_get_callbacks(); if (cbs) - cbs->register_bss(wpa_s, bssid); + cbs->register_bss(wpa_s, bssid, id); wpa_msg_ctrl(wpa_s, MSG_INFO, WPA_EVENT_BSS_ADDED "%u " MACSTR, id, MAC2STR(bssid)); } @@ -255,7 +255,7 @@ void wpas_notify_bss_removed(struct wpa_supplicant *wpa_s, { struct wpas_dbus_callbacks *cbs = wpas_dbus_get_callbacks(); if (cbs) - cbs->unregister_bss(wpa_s, bssid); + cbs->unregister_bss(wpa_s, bssid, id); wpa_msg_ctrl(wpa_s, MSG_INFO, WPA_EVENT_BSS_REMOVED "%u " MACSTR, id, MAC2STR(bssid)); }