dbus: Change WPA/RSNIE byte array props to dicts

Expose RSN and WPA properties for BSS objects containing information
about key management and cipher suites. Get rid of WPA/RSN/WPSIE
byte array properties and add IEs byte array property with all IE data
instead.
This commit is contained in:
Witold Sowa 2010-01-16 16:37:37 +02:00 committed by Jouni Malinen
parent 8c0906542c
commit 7899e2f42d
9 changed files with 209 additions and 70 deletions

View file

@ -620,16 +620,27 @@ scan results.
<p>SSID of the BSS.</p> <p>SSID of the BSS.</p>
</li> </li>
<li> <li>
<h3>WPAIE - ay - (read)</h3> <h3>WPA - a{sv} - (read)</h3>
<p>WPA information element of the BSS. The second byte contain number of bytes following it.</p> <p>WPA information of the BSS. Empty dictionary indicates no WPA support. Dictionary entries are:</p>
<table>
<tr><td>KeyMgmt</td><td>as</td><td>Key management suite. Possible array elements: "wpa-psk", "wpa-eap", "wpa-none"</td>
<tr><td>Pairwise</td><td>as</td><td>Pairwise cipher suites. Possible array elements: "ccmp", "tkip"</td>
<tr><td>Group</td><td>s</td><td>Group cipher suite. Possible values are: "ccmp", "tkip", "wep104", "wep40"</td>
</table>
</li> </li>
<li> <li>
<h3>RSNIE - ay - (read)</h3> <h3>RSN - a{sv} - (read)</h3>
<p>RSN information element of the BSS. The second byte contain number of bytes following it.</p> <p>RSN information of the BSS. Empty dictionary indicates no RSN support. Dictionary entries are:</p>
<table>
<tr><td>KeyMgmt</td><td>as</td><td>Key management suite. Possible array elements: "wpa-psk", "wpa-eap", "wpa-ft-psk", "wpa-ft-eap", "wpa-psk-sha256", "wpa-eap-sha256",</td>
<tr><td>Pairwise</td><td>as</td><td>Pairwise cipher suites. Possible array elements: "ccmp", "tkip"</td>
<tr><td>Group</td><td>s</td><td>Group cipher suite. Possible values are: "ccmp", "tkip", "wep104", "wep40"</td>
<tr><td>MgmtGroup</td><td>s</td><td>Mangement frames cipher suite. Possible values are: "aes128cmac"</td>
</table>
</li> </li>
<li> <li>
<h3>WPSIE - ay - (read)</h3> <h3>IEs - ay - (read)</h3>
<p>WPS information element of the BSS. The second byte contain number of bytes following it.</p> <p>All IEs of the BSS as a chain of TLVs</p>
</li> </li>
<li> <li>
<h3>Privacy - b - (read)</h3> <h3>Privacy - b - (read)</h3>

View file

@ -60,6 +60,7 @@
#define WPA_BSS_RSNIE_CHANGED_FLAG BIT(5) #define WPA_BSS_RSNIE_CHANGED_FLAG BIT(5)
#define WPA_BSS_WPS_CHANGED_FLAG BIT(6) #define WPA_BSS_WPS_CHANGED_FLAG BIT(6)
#define WPA_BSS_RATES_CHANGED_FLAG BIT(7) #define WPA_BSS_RATES_CHANGED_FLAG BIT(7)
#define WPA_BSS_IES_CHANGED_FLAG BIT(8)
static void wpa_bss_remove(struct wpa_supplicant *wpa_s, struct wpa_bss *bss) static void wpa_bss_remove(struct wpa_supplicant *wpa_s, struct wpa_bss *bss)
@ -217,6 +218,11 @@ static u32 wpa_bss_compare_res(const struct wpa_bss *old,
if (caps_diff & IEEE80211_CAP_IBSS) if (caps_diff & IEEE80211_CAP_IBSS)
changes |= WPA_BSS_MODE_CHANGED_FLAG; changes |= WPA_BSS_MODE_CHANGED_FLAG;
if (old->ie_len == new->ie_len &&
os_memcmp(old + 1, new + 1, old->ie_len) == 0)
return changes;
changes |= WPA_BSS_IES_CHANGED_FLAG;
if (!are_ies_equal(old, new, WPA_IE_VENDOR_TYPE)) if (!are_ies_equal(old, new, WPA_IE_VENDOR_TYPE))
changes |= WPA_BSS_WPAIE_CHANGED_FLAG; changes |= WPA_BSS_WPAIE_CHANGED_FLAG;
@ -258,6 +264,9 @@ static void notify_bss_changes(struct wpa_supplicant *wpa_s, u32 changes,
if (changes & WPA_BSS_WPS_CHANGED_FLAG) if (changes & WPA_BSS_WPS_CHANGED_FLAG)
wpas_notify_bss_wps_changed(wpa_s, bss->id); wpas_notify_bss_wps_changed(wpa_s, bss->id);
if (changes & WPA_BSS_IES_CHANGED_FLAG)
wpas_notify_bss_ies_changed(wpa_s, bss->id);
if (changes & WPA_BSS_RATES_CHANGED_FLAG) if (changes & WPA_BSS_RATES_CHANGED_FLAG)
wpas_notify_bss_rates_changed(wpa_s, bss->id); wpas_notify_bss_rates_changed(wpa_s, bss->id);
} }

View file

@ -732,14 +732,14 @@ void wpas_dbus_bss_signal_prop_changed(struct wpa_supplicant *wpa_s,
case WPAS_DBUS_BSS_PROP_RATES: case WPAS_DBUS_BSS_PROP_RATES:
prop = "Rates"; prop = "Rates";
break; break;
case WPAS_DBUS_BSS_PROP_WPAIE: case WPAS_DBUS_BSS_PROP_WPA:
prop = "WPAIE"; prop = "WPA";
break; break;
case WPAS_DBUS_BSS_PROP_RSNIE: case WPAS_DBUS_BSS_PROP_RSN:
prop = "RSNIE"; prop = "RSN";
break; break;
case WPAS_DBUS_BSS_PROP_WPSIE: case WPAS_DBUS_BSS_PROP_IES:
prop = "WPSIE"; prop = "IEs";
break; break;
default: default:
wpa_printf(MSG_ERROR, "dbus: %s: Unknown Property value %d", wpa_printf(MSG_ERROR, "dbus: %s: Unknown Property value %d",
@ -1131,18 +1131,18 @@ static const struct wpa_dbus_property_desc wpas_dbus_bss_properties[] = {
NULL, NULL,
R R
}, },
{ "WPAIE", WPAS_DBUS_NEW_IFACE_BSS, "ay", { "WPA", WPAS_DBUS_NEW_IFACE_BSS, "a{sv}",
(WPADBusPropertyAccessor) wpas_dbus_getter_bss_wpaie, (WPADBusPropertyAccessor) wpas_dbus_getter_bss_wpa,
NULL, NULL,
R R
}, },
{ "RSNIE", WPAS_DBUS_NEW_IFACE_BSS, "ay", { "RSN", WPAS_DBUS_NEW_IFACE_BSS, "a{sv}",
(WPADBusPropertyAccessor) wpas_dbus_getter_bss_rsnie, (WPADBusPropertyAccessor) wpas_dbus_getter_bss_rsn,
NULL, NULL,
R R
}, },
{ "WPSIE", WPAS_DBUS_NEW_IFACE_BSS, "ay", { "IEs", WPAS_DBUS_NEW_IFACE_BSS, "ay",
(WPADBusPropertyAccessor) wpas_dbus_getter_bss_wpsie, (WPADBusPropertyAccessor) wpas_dbus_getter_bss_ies,
NULL, NULL,
R R
}, },

View file

@ -38,9 +38,9 @@ enum wpas_dbus_bss_prop {
WPAS_DBUS_BSS_PROP_MODE, WPAS_DBUS_BSS_PROP_MODE,
WPAS_DBUS_BSS_PROP_PRIVACY, WPAS_DBUS_BSS_PROP_PRIVACY,
WPAS_DBUS_BSS_PROP_RATES, WPAS_DBUS_BSS_PROP_RATES,
WPAS_DBUS_BSS_PROP_WPAIE, WPAS_DBUS_BSS_PROP_WPA,
WPAS_DBUS_BSS_PROP_RSNIE, WPAS_DBUS_BSS_PROP_RSN,
WPAS_DBUS_BSS_PROP_WPSIE, WPAS_DBUS_BSS_PROP_IES,
}; };
#define WPAS_DBUS_OBJECT_PATH_MAX 150 #define WPAS_DBUS_OBJECT_PATH_MAX 150

View file

@ -1,7 +1,7 @@
/* /*
* WPA Supplicant / dbus-based control interface * WPA Supplicant / dbus-based control interface
* Copyright (c) 2006, Dan Williams <dcbw@redhat.com> and Red Hat, Inc. * Copyright (c) 2006, Dan Williams <dcbw@redhat.com> and Red Hat, Inc.
* Copyright (c) 2009, Witold Sowa <witold.sowa@gmail.com> * Copyright (c) 2009-2010, Witold Sowa <witold.sowa@gmail.com>
* Copyright (c) 2009, Jouni Malinen <j@w1.fi> * Copyright (c) 2009, Jouni Malinen <j@w1.fi>
* *
* This program is free software; you can redistribute it and/or modify * This program is free software; you can redistribute it and/or modify
@ -20,6 +20,7 @@
#include "common/ieee802_11_defs.h" #include "common/ieee802_11_defs.h"
#include "eap_peer/eap_methods.h" #include "eap_peer/eap_methods.h"
#include "eapol_supp/eapol_supp_sm.h" #include "eapol_supp/eapol_supp_sm.h"
#include "rsn_supp/wpa.h"
#include "../config.h" #include "../config.h"
#include "../wpa_supplicant_i.h" #include "../wpa_supplicant_i.h"
#include "../driver_i.h" #include "../driver_i.h"
@ -2560,90 +2561,199 @@ DBusMessage * wpas_dbus_getter_bss_rates(DBusMessage *message,
} }
static DBusMessage * wpas_dbus_get_bss_security_prop(
DBusMessage *message, struct wpa_ie_data *ie_data)
{
DBusMessage *reply;
DBusMessageIter iter, iter_dict, variant_iter;
const char *group;
const char *pairwise[2]; /* max 2 pairwise ciphers is supported */
const char *key_mgmt[7]; /* max 7 key managements may be supported */
int n;
if (message == NULL)
reply = dbus_message_new(DBUS_MESSAGE_TYPE_SIGNAL);
else
reply = dbus_message_new_method_return(message);
if (!reply)
goto nomem;
dbus_message_iter_init_append(reply, &iter);
if (!dbus_message_iter_open_container(&iter, DBUS_TYPE_VARIANT,
"a{sv}", &variant_iter))
goto nomem;
if (!wpa_dbus_dict_open_write(&variant_iter, &iter_dict))
goto nomem;
/* KeyMgmt */
n = 0;
if (ie_data->key_mgmt & WPA_KEY_MGMT_PSK)
key_mgmt[n++] = "wpa-psk";
if (ie_data->key_mgmt & WPA_KEY_MGMT_FT_PSK)
key_mgmt[n++] = "wpa-ft-psk";
if (ie_data->key_mgmt & WPA_KEY_MGMT_PSK_SHA256)
key_mgmt[n++] = "wpa-psk-sha256";
if (ie_data->key_mgmt & WPA_KEY_MGMT_IEEE8021X)
key_mgmt[n++] = "wpa-eap";
if (ie_data->key_mgmt & WPA_KEY_MGMT_FT_IEEE8021X)
key_mgmt[n++] = "wpa-ft-eap";
if (ie_data->key_mgmt & WPA_KEY_MGMT_IEEE8021X_SHA256)
key_mgmt[n++] = "wpa-eap-sha256";
if (ie_data->key_mgmt & WPA_KEY_MGMT_NONE)
key_mgmt[n++] = "wpa-none";
if (!wpa_dbus_dict_append_string_array(&iter_dict, "KeyMgmt",
key_mgmt, n))
goto nomem;
/* Group */
switch (ie_data->group_cipher) {
case WPA_CIPHER_WEP40:
group = "wep40";
break;
case WPA_CIPHER_TKIP:
group = "tkip";
break;
case WPA_CIPHER_CCMP:
group = "ccmp";
break;
case WPA_CIPHER_WEP104:
group = "wep104";
break;
default:
group = "";
break;
}
if (!wpa_dbus_dict_append_string(&iter_dict, "Group", group))
goto nomem;
/* Pairwise */
n = 0;
if (ie_data->pairwise_cipher & WPA_CIPHER_TKIP)
pairwise[n++] = "tkip";
if (ie_data->pairwise_cipher & WPA_CIPHER_CCMP)
pairwise[n++] = "ccmp";
if (!wpa_dbus_dict_append_string_array(&iter_dict, "Pairwise",
pairwise, n))
goto nomem;
/* Management group (RSN only) */
if (ie_data->proto == WPA_PROTO_RSN) {
switch (ie_data->mgmt_group_cipher) {
#ifdef CONFIG_IEEE80211W
case WPA_CIPHER_AES_128_CMAC:
group = "aes128cmac";
break;
#endif /* CONFIG_IEEE80211W */
default:
group = "";
break;
}
if (!wpa_dbus_dict_append_string(&iter_dict, "MgmtGroup",
group))
goto nomem;
}
if (!wpa_dbus_dict_close_write(&variant_iter, &iter_dict))
goto nomem;
if (!dbus_message_iter_close_container(&iter, &variant_iter))
goto nomem;
return reply;
nomem:
if (reply)
dbus_message_unref(reply);
return dbus_message_new_error(message, DBUS_ERROR_NO_MEMORY, NULL);
}
/** /**
* wpas_dbus_getter_bss_wpaie - Return the WPA IE of a BSS * wpas_dbus_getter_bss_wpa - Return the WPA options of a BSS
* @message: Pointer to incoming dbus message * @message: Pointer to incoming dbus message
* @bss: a pair of interface describing structure and bss's id * @bss: a pair of interface describing structure and bss's id
* Returns: a dbus message containing the WPA information elements * Returns: a dbus message containing the WPA options of requested bss
* of requested bss
* *
* Getter for "WPAIE" property. * Getter for "WPA" property.
*/ */
DBusMessage * wpas_dbus_getter_bss_wpaie(DBusMessage *message, DBusMessage * wpas_dbus_getter_bss_wpa(DBusMessage *message,
struct bss_handler_args *bss) struct bss_handler_args *bss)
{ {
struct wpa_bss *res = wpa_bss_get_id(bss->wpa_s, bss->id); struct wpa_bss *res = wpa_bss_get_id(bss->wpa_s, bss->id);
struct wpa_ie_data wpa_data;
const u8 *ie; const u8 *ie;
if (!res) { if (!res) {
wpa_printf(MSG_ERROR, "wpas_dbus_getter_bss_wpaie[dbus]: no " wpa_printf(MSG_ERROR, "wpas_dbus_getter_bss_wpa[dbus]: no "
"bss with id %d found", bss->id); "bss with id %d found", bss->id);
return NULL; return NULL;
} }
os_memset(&wpa_data, 0, sizeof(wpa_data));
ie = wpa_bss_get_vendor_ie(res, WPA_IE_VENDOR_TYPE); ie = wpa_bss_get_vendor_ie(res, WPA_IE_VENDOR_TYPE);
if (!ie) if (ie)
return NULL; wpa_parse_wpa_ie(ie, 2 + ie[1], &wpa_data);
return wpas_dbus_simple_array_property_getter(message, DBUS_TYPE_BYTE,
ie, ie[1] + 2); return wpas_dbus_get_bss_security_prop(message, &wpa_data);
} }
/** /**
* wpas_dbus_getter_bss_rsnie - Return the RSN IE of a BSS * wpas_dbus_getter_bss_rsn - Return the RSN options of a BSS
* @message: Pointer to incoming dbus message * @message: Pointer to incoming dbus message
* @bss: a pair of interface describing structure and bss's id * @bss: a pair of interface describing structure and bss's id
* Returns: a dbus message containing the RSN information elements * Returns: a dbus message containing the RSN options of requested bss
* of requested bss
* *
* Getter for "RSNIE" property. * Getter for "RSN" property.
*/ */
DBusMessage * wpas_dbus_getter_bss_rsnie(DBusMessage *message, DBusMessage * wpas_dbus_getter_bss_rsn(DBusMessage *message,
struct bss_handler_args *bss) struct bss_handler_args *bss)
{ {
struct wpa_bss *res = wpa_bss_get_id(bss->wpa_s, bss->id); struct wpa_bss *res = wpa_bss_get_id(bss->wpa_s, bss->id);
struct wpa_ie_data wpa_data;
const u8 *ie; const u8 *ie;
if (!res) { if (!res) {
wpa_printf(MSG_ERROR, "wpas_dbus_getter_bss_rsnie[dbus]: no " wpa_printf(MSG_ERROR, "wpas_dbus_getter_bss_rsn[dbus]: no "
"bss with id %d found", bss->id); "bss with id %d found", bss->id);
return NULL; return NULL;
} }
os_memset(&wpa_data, 0, sizeof(wpa_data));
ie = wpa_bss_get_ie(res, WLAN_EID_RSN); ie = wpa_bss_get_ie(res, WLAN_EID_RSN);
if (!ie) if (ie)
return NULL; wpa_parse_wpa_ie(ie, 2 + ie[1], &wpa_data);
return wpas_dbus_simple_array_property_getter(message, DBUS_TYPE_BYTE,
ie, ie[1] + 2); return wpas_dbus_get_bss_security_prop(message, &wpa_data);
} }
/** /**
* wpas_dbus_getter_bss_wpsie - Return the WPS IE of a BSS * wpas_dbus_getter_bss_ies - Return all IEs of a BSS
* @message: Pointer to incoming dbus message * @message: Pointer to incoming dbus message
* @bss: a pair of interface describing structure and bss's id * @bss: a pair of interface describing structure and bss's id
* Returns: a dbus message containing the WPS information elements * Returns: a dbus message containing IEs byte array
* of requested bss
* *
* Getter for "WPSIE" property. * Getter for "IEs" property.
*/ */
DBusMessage * wpas_dbus_getter_bss_wpsie(DBusMessage *message, DBusMessage * wpas_dbus_getter_bss_ies(DBusMessage *message,
struct bss_handler_args *bss) struct bss_handler_args *bss)
{ {
struct wpa_bss *res = wpa_bss_get_id(bss->wpa_s, bss->id); struct wpa_bss *res = wpa_bss_get_id(bss->wpa_s, bss->id);
const u8 *ie;
if (!res) { if (!res) {
wpa_printf(MSG_ERROR, "wpas_dbus_getter_bss_wpsie[dbus]: no " wpa_printf(MSG_ERROR, "wpas_dbus_getter_bss_ies[dbus]: no "
"bss with id %d found", bss->id); "bss with id %d found", bss->id);
return NULL; return NULL;
} }
ie = wpa_bss_get_vendor_ie(res, WPS_IE_VENDOR_TYPE);
if (!ie)
return NULL;
return wpas_dbus_simple_array_property_getter(message, DBUS_TYPE_BYTE, return wpas_dbus_simple_array_property_getter(message, DBUS_TYPE_BYTE,
ie, ie[1] + 2); res + 1, res->ie_len);
} }

View file

@ -1,6 +1,7 @@
/* /*
* WPA Supplicant / dbus-based control interface * WPA Supplicant / dbus-based control interface
* Copyright (c) 2006, Dan Williams <dcbw@redhat.com> and Red Hat, Inc. * Copyright (c) 2006, Dan Williams <dcbw@redhat.com> and Red Hat, Inc.
* Copyright (c) 2009-2010, Witold Sowa <witold.sowa@gmail.com>
* *
* This program is free software; you can redistribute it and/or modify * 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 * it under the terms of the GNU General Public License version 2 as
@ -154,14 +155,14 @@ DBusMessage * wpas_dbus_getter_bss_frequency(DBusMessage *message,
DBusMessage * wpas_dbus_getter_bss_rates(DBusMessage *message, DBusMessage * wpas_dbus_getter_bss_rates(DBusMessage *message,
struct bss_handler_args *bss); struct bss_handler_args *bss);
DBusMessage * wpas_dbus_getter_bss_wpaie(DBusMessage *message, DBusMessage * wpas_dbus_getter_bss_wpa(DBusMessage *message,
struct bss_handler_args *bss); struct bss_handler_args *bss);
DBusMessage * wpas_dbus_getter_bss_rsnie(DBusMessage *message, DBusMessage * wpas_dbus_getter_bss_rsn(DBusMessage *message,
struct bss_handler_args *bss); struct bss_handler_args *bss);
DBusMessage * wpas_dbus_getter_bss_wpsie(DBusMessage *message, DBusMessage * wpas_dbus_getter_bss_ies(DBusMessage *message,
struct bss_handler_args *bss); struct bss_handler_args *bss);
DBusMessage * wpas_dbus_getter_enabled(DBusMessage *message, DBusMessage * wpas_dbus_getter_enabled(DBusMessage *message,
struct network_handler_args *net); struct network_handler_args *net);

View file

@ -52,15 +52,15 @@ def showBss(bss):
dbus_interface=dbus.PROPERTIES_IFACE) dbus_interface=dbus.PROPERTIES_IFACE)
ssid = byte_array_to_string(val) ssid = byte_array_to_string(val)
val = net_obj.Get(WPAS_DBUS_BSS_INTERFACE, 'WPAIE', val = net_obj.Get(WPAS_DBUS_BSS_INTERFACE, 'WPA',
dbus_interface=dbus.PROPERTIES_IFACE) dbus_interface=dbus.PROPERTIES_IFACE)
wpa = "no" wpa = "no"
if val != None: if len(val["KeyMgmt"]) > 0:
wpa = "yes" wpa = "yes"
val = net_obj.Get(WPAS_DBUS_BSS_INTERFACE, 'RSNIE', val = net_obj.Get(WPAS_DBUS_BSS_INTERFACE, 'RSN',
dbus_interface=dbus.PROPERTIES_IFACE) dbus_interface=dbus.PROPERTIES_IFACE)
wpa2 = "no" wpa2 = "no"
if val != None: if len(val["KeyMgmt"]) > 0:
wpa2 = "yes" wpa2 = "yes"
freq = net_obj.Get(WPAS_DBUS_BSS_INTERFACE, 'Frequency', freq = net_obj.Get(WPAS_DBUS_BSS_INTERFACE, 'Frequency',
dbus_interface=dbus.PROPERTIES_IFACE) dbus_interface=dbus.PROPERTIES_IFACE)

View file

@ -242,21 +242,27 @@ void wpas_notify_bss_mode_changed(struct wpa_supplicant *wpa_s,
void wpas_notify_bss_wpaie_changed(struct wpa_supplicant *wpa_s, void wpas_notify_bss_wpaie_changed(struct wpa_supplicant *wpa_s,
unsigned int id) unsigned int id)
{ {
wpas_dbus_bss_signal_prop_changed(wpa_s, WPAS_DBUS_BSS_PROP_WPAIE, id); wpas_dbus_bss_signal_prop_changed(wpa_s, WPAS_DBUS_BSS_PROP_WPA, id);
} }
void wpas_notify_bss_rsnie_changed(struct wpa_supplicant *wpa_s, void wpas_notify_bss_rsnie_changed(struct wpa_supplicant *wpa_s,
unsigned int id) unsigned int id)
{ {
wpas_dbus_bss_signal_prop_changed(wpa_s, WPAS_DBUS_BSS_PROP_RSNIE, id); wpas_dbus_bss_signal_prop_changed(wpa_s, WPAS_DBUS_BSS_PROP_RSN, id);
} }
void wpas_notify_bss_wps_changed(struct wpa_supplicant *wpa_s, void wpas_notify_bss_wps_changed(struct wpa_supplicant *wpa_s,
unsigned int id)
{
}
void wpas_notify_bss_ies_changed(struct wpa_supplicant *wpa_s,
unsigned int id) unsigned int id)
{ {
wpas_dbus_bss_signal_prop_changed(wpa_s, WPAS_DBUS_BSS_PROP_WPSIE, id); wpas_dbus_bss_signal_prop_changed(wpa_s, WPAS_DBUS_BSS_PROP_IES, id);
} }

View file

@ -64,7 +64,9 @@ void wpas_notify_bss_wpaie_changed(struct wpa_supplicant *wpa_s,
void wpas_notify_bss_rsnie_changed(struct wpa_supplicant *wpa_s, void wpas_notify_bss_rsnie_changed(struct wpa_supplicant *wpa_s,
unsigned int id); unsigned int id);
void wpas_notify_bss_wps_changed(struct wpa_supplicant *wpa_s, void wpas_notify_bss_wps_changed(struct wpa_supplicant *wpa_s,
unsigned int id); unsigned int id);
void wpas_notify_bss_ies_changed(struct wpa_supplicant *wpa_s,
unsigned int id);
void wpas_notify_bss_rates_changed(struct wpa_supplicant *wpa_s, void wpas_notify_bss_rates_changed(struct wpa_supplicant *wpa_s,
unsigned int id); unsigned int id);
void wpas_notify_blob_added(struct wpa_supplicant *wpa_s, const char *name); void wpas_notify_blob_added(struct wpa_supplicant *wpa_s, const char *name);