dbus: Add BSS property change notifications
This commit is contained in:
parent
c3299a8b74
commit
158c6c7467
5 changed files with 281 additions and 0 deletions
|
@ -52,6 +52,15 @@
|
|||
*/
|
||||
#define WPA_BSS_EXPIRATION_SCAN_COUNT 2
|
||||
|
||||
#define WPA_BSS_FREQ_CHANGED_FLAG BIT(0)
|
||||
#define WPA_BSS_SIGNAL_CHANGED_FLAG BIT(1)
|
||||
#define WPA_BSS_PRIVACY_CHANGED_FLAG BIT(2)
|
||||
#define WPA_BSS_MODE_CHANGED_FLAG BIT(3)
|
||||
#define WPA_BSS_WPAIE_CHANGED_FLAG BIT(4)
|
||||
#define WPA_BSS_RSNIE_CHANGED_FLAG BIT(5)
|
||||
#define WPA_BSS_WPS_CHANGED_FLAG BIT(6)
|
||||
#define WPA_BSS_RATES_CHANGED_FLAG BIT(7)
|
||||
|
||||
|
||||
static void wpa_bss_remove(struct wpa_supplicant *wpa_s, struct wpa_bss *bss)
|
||||
{
|
||||
|
@ -136,9 +145,129 @@ static void wpa_bss_add(struct wpa_supplicant *wpa_s,
|
|||
}
|
||||
|
||||
|
||||
static int are_ies_equal(const struct wpa_bss *old,
|
||||
const struct wpa_scan_res *new, u32 ie)
|
||||
{
|
||||
const u8 *old_ie, *new_ie;
|
||||
struct wpabuf *old_ie_buff = NULL;
|
||||
struct wpabuf *new_ie_buff = NULL;
|
||||
int new_ie_len, old_ie_len, ret, is_multi;
|
||||
|
||||
switch (ie) {
|
||||
case WPA_IE_VENDOR_TYPE:
|
||||
old_ie = wpa_bss_get_vendor_ie(old, ie);
|
||||
new_ie = wpa_scan_get_vendor_ie(new, ie);
|
||||
is_multi = 0;
|
||||
break;
|
||||
case WPS_IE_VENDOR_TYPE:
|
||||
old_ie_buff = wpa_bss_get_vendor_ie_multi(old, ie);
|
||||
new_ie_buff = wpa_scan_get_vendor_ie_multi(new, ie);
|
||||
is_multi = 1;
|
||||
break;
|
||||
case WLAN_EID_RSN:
|
||||
case WLAN_EID_SUPP_RATES:
|
||||
case WLAN_EID_EXT_SUPP_RATES:
|
||||
old_ie = wpa_bss_get_ie(old, ie);
|
||||
new_ie = wpa_scan_get_ie(new, ie);
|
||||
is_multi = 0;
|
||||
break;
|
||||
default:
|
||||
wpa_printf(MSG_DEBUG, "bss: %s: cannot compare IEs", __func__);
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (is_multi) {
|
||||
/* in case of multiple IEs stored in buffer */
|
||||
old_ie = old_ie_buff ? wpabuf_head_u8(old_ie_buff) : NULL;
|
||||
new_ie = new_ie_buff ? wpabuf_head_u8(new_ie_buff) : NULL;
|
||||
old_ie_len = old_ie_buff ? wpabuf_len(old_ie_buff) : 0;
|
||||
new_ie_len = new_ie_buff ? wpabuf_len(new_ie_buff) : 0;
|
||||
} else {
|
||||
/* in case of single IE */
|
||||
old_ie_len = old_ie ? old_ie[1] + 2 : 0;
|
||||
new_ie_len = new_ie ? new_ie[1] + 2 : 0;
|
||||
}
|
||||
|
||||
ret = (old_ie_len == new_ie_len &&
|
||||
os_memcmp(old_ie, new_ie, old_ie_len) == 0);
|
||||
|
||||
wpabuf_free(old_ie_buff);
|
||||
wpabuf_free(new_ie_buff);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
static u32 wpa_bss_compare_res(const struct wpa_bss *old,
|
||||
const struct wpa_scan_res *new)
|
||||
{
|
||||
u32 changes = 0;
|
||||
int caps_diff = old->caps ^ new->caps;
|
||||
|
||||
if (old->freq != new->freq)
|
||||
changes |= WPA_BSS_FREQ_CHANGED_FLAG;
|
||||
|
||||
if (old->level != new->level)
|
||||
changes |= WPA_BSS_SIGNAL_CHANGED_FLAG;
|
||||
|
||||
if (caps_diff & IEEE80211_CAP_PRIVACY)
|
||||
changes |= WPA_BSS_PRIVACY_CHANGED_FLAG;
|
||||
|
||||
if (caps_diff & IEEE80211_CAP_IBSS)
|
||||
changes |= WPA_BSS_MODE_CHANGED_FLAG;
|
||||
|
||||
if (!are_ies_equal(old, new, WPA_IE_VENDOR_TYPE))
|
||||
changes |= WPA_BSS_WPAIE_CHANGED_FLAG;
|
||||
|
||||
if (!are_ies_equal(old, new, WLAN_EID_RSN))
|
||||
changes |= WPA_BSS_RSNIE_CHANGED_FLAG;
|
||||
|
||||
if (!are_ies_equal(old, new, WPS_IE_VENDOR_TYPE))
|
||||
changes |= WPA_BSS_WPS_CHANGED_FLAG;
|
||||
|
||||
if (!are_ies_equal(old, new, WLAN_EID_SUPP_RATES) ||
|
||||
!are_ies_equal(old, new, WLAN_EID_EXT_SUPP_RATES))
|
||||
changes |= WPA_BSS_RATES_CHANGED_FLAG;
|
||||
|
||||
return changes;
|
||||
}
|
||||
|
||||
|
||||
static void notify_bss_changes(struct wpa_supplicant *wpa_s, u32 changes,
|
||||
const struct wpa_bss *bss)
|
||||
{
|
||||
if (changes & WPA_BSS_FREQ_CHANGED_FLAG)
|
||||
wpas_notify_bss_freq_changed(wpa_s, bss->id);
|
||||
|
||||
if (changes & WPA_BSS_SIGNAL_CHANGED_FLAG)
|
||||
wpas_notify_bss_signal_changed(wpa_s, bss->id);
|
||||
|
||||
if (changes & WPA_BSS_PRIVACY_CHANGED_FLAG)
|
||||
wpas_notify_bss_privacy_changed(wpa_s, bss->id);
|
||||
|
||||
if (changes & WPA_BSS_MODE_CHANGED_FLAG)
|
||||
wpas_notify_bss_mode_changed(wpa_s, bss->id);
|
||||
|
||||
if (changes & WPA_BSS_WPAIE_CHANGED_FLAG)
|
||||
wpas_notify_bss_wpaie_changed(wpa_s, bss->id);
|
||||
|
||||
if (changes & WPA_BSS_RSNIE_CHANGED_FLAG)
|
||||
wpas_notify_bss_rsnie_changed(wpa_s, bss->id);
|
||||
|
||||
if (changes & WPA_BSS_WPS_CHANGED_FLAG)
|
||||
wpas_notify_bss_wps_changed(wpa_s, bss->id);
|
||||
|
||||
if (changes & WPA_BSS_RATES_CHANGED_FLAG)
|
||||
wpas_notify_bss_rates_changed(wpa_s, bss->id);
|
||||
}
|
||||
|
||||
|
||||
static void wpa_bss_update(struct wpa_supplicant *wpa_s, struct wpa_bss *bss,
|
||||
struct wpa_scan_res *res)
|
||||
{
|
||||
u32 changes;
|
||||
|
||||
changes = wpa_bss_compare_res(bss, res);
|
||||
bss->scan_miss_count = 0;
|
||||
bss->last_update_idx = wpa_s->bss_update_idx;
|
||||
wpa_bss_copy_res(bss, res);
|
||||
|
@ -160,6 +289,8 @@ static void wpa_bss_update(struct wpa_supplicant *wpa_s, struct wpa_bss *bss,
|
|||
dl_list_add(prev, &bss->list_id);
|
||||
}
|
||||
dl_list_add_tail(&wpa_s->bss, &bss->list);
|
||||
|
||||
notify_bss_changes(wpa_s, changes, bss);
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -700,6 +700,62 @@ void wpas_dbus_signal_prop_changed(struct wpa_supplicant *wpa_s,
|
|||
}
|
||||
|
||||
|
||||
/**
|
||||
* wpas_dbus_bss_signal_prop_changed - Signals change of BSS property
|
||||
* @wpa_s: %wpa_supplicant network interface data
|
||||
* @property: indicates which property has changed
|
||||
* @id: unique BSS identifier
|
||||
*
|
||||
* Sends PropertyChanged signals with path, interface, and arguments depending
|
||||
* on which property has changed.
|
||||
*/
|
||||
void wpas_dbus_bss_signal_prop_changed(struct wpa_supplicant *wpa_s,
|
||||
enum wpas_dbus_bss_prop property,
|
||||
unsigned int id)
|
||||
{
|
||||
char path[WPAS_DBUS_OBJECT_PATH_MAX];
|
||||
char *prop;
|
||||
|
||||
switch (property) {
|
||||
case WPAS_DBUS_BSS_PROP_SIGNAL:
|
||||
prop = "Signal";
|
||||
break;
|
||||
case WPAS_DBUS_BSS_PROP_FREQ:
|
||||
prop = "Frequency";
|
||||
break;
|
||||
case WPAS_DBUS_BSS_PROP_MODE:
|
||||
prop = "Mode";
|
||||
break;
|
||||
case WPAS_DBUS_BSS_PROP_PRIVACY:
|
||||
prop = "Privacy";
|
||||
break;
|
||||
case WPAS_DBUS_BSS_PROP_RATES:
|
||||
prop = "Rates";
|
||||
break;
|
||||
case WPAS_DBUS_BSS_PROP_WPAIE:
|
||||
prop = "WPAIE";
|
||||
break;
|
||||
case WPAS_DBUS_BSS_PROP_RSNIE:
|
||||
prop = "RSNIE";
|
||||
break;
|
||||
case WPAS_DBUS_BSS_PROP_WPSIE:
|
||||
prop = "WPSIE";
|
||||
break;
|
||||
default:
|
||||
wpa_printf(MSG_ERROR, "dbus: %s: Unknown Property value %d",
|
||||
__func__, property);
|
||||
return;
|
||||
}
|
||||
|
||||
os_snprintf(path, WPAS_DBUS_OBJECT_PATH_MAX,
|
||||
"%s/" WPAS_DBUS_NEW_BSSIDS_PART "/%u",
|
||||
wpa_s->dbus_new_path, id);
|
||||
|
||||
wpa_dbus_mark_property_changed(wpa_s->global->dbus, path,
|
||||
WPAS_DBUS_NEW_IFACE_BSSID, prop);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* wpas_dbus_signal_debug_level_changed - Signals change of debug param
|
||||
* @global: wpa_global structure
|
||||
|
|
|
@ -32,6 +32,17 @@ enum wpas_dbus_prop {
|
|||
WPAS_DBUS_PROP_CURRENT_NETWORK,
|
||||
};
|
||||
|
||||
enum wpas_dbus_bss_prop {
|
||||
WPAS_DBUS_BSS_PROP_SIGNAL,
|
||||
WPAS_DBUS_BSS_PROP_FREQ,
|
||||
WPAS_DBUS_BSS_PROP_MODE,
|
||||
WPAS_DBUS_BSS_PROP_PRIVACY,
|
||||
WPAS_DBUS_BSS_PROP_RATES,
|
||||
WPAS_DBUS_BSS_PROP_WPAIE,
|
||||
WPAS_DBUS_BSS_PROP_RSNIE,
|
||||
WPAS_DBUS_BSS_PROP_WPSIE,
|
||||
};
|
||||
|
||||
#define WPAS_DBUS_OBJECT_PATH_MAX 150
|
||||
|
||||
#define WPAS_DBUS_NEW_SERVICE "fi.w1.wpa_supplicant1"
|
||||
|
@ -80,6 +91,9 @@ int wpas_dbus_register_interface(struct wpa_supplicant *wpa_s);
|
|||
int wpas_dbus_unregister_interface(struct wpa_supplicant *wpa_s);
|
||||
void wpas_dbus_signal_prop_changed(struct wpa_supplicant *wpa_s,
|
||||
enum wpas_dbus_prop property);
|
||||
void wpas_dbus_bss_signal_prop_changed(struct wpa_supplicant *wpa_s,
|
||||
enum wpas_dbus_bss_prop property,
|
||||
unsigned int id);
|
||||
void wpas_dbus_signal_network_enabled_changed(struct wpa_supplicant *wpa_s,
|
||||
struct wpa_ssid *ssid);
|
||||
void wpas_dbus_signal_network_selected(struct wpa_supplicant *wpa_s, int id);
|
||||
|
@ -125,6 +139,12 @@ static inline void wpas_dbus_signal_prop_changed(struct wpa_supplicant *wpa_s,
|
|||
{
|
||||
}
|
||||
|
||||
static inline void wpas_dbus_bss_signal_prop_changed(
|
||||
struct wpa_supplicant *wpa_s, enum wpas_dbus_bss_prop property,
|
||||
unsigned int id)
|
||||
{
|
||||
}
|
||||
|
||||
static inline void wpas_dbus_signal_network_enabled_changed(
|
||||
struct wpa_supplicant *wpa_s, struct wpa_ssid *ssid)
|
||||
{
|
||||
|
|
|
@ -209,6 +209,64 @@ void wpas_notify_bss_removed(struct wpa_supplicant *wpa_s,
|
|||
}
|
||||
|
||||
|
||||
void wpas_notify_bss_freq_changed(struct wpa_supplicant *wpa_s,
|
||||
unsigned int id)
|
||||
{
|
||||
wpas_dbus_bss_signal_prop_changed(wpa_s, WPAS_DBUS_BSS_PROP_FREQ, id);
|
||||
}
|
||||
|
||||
|
||||
void wpas_notify_bss_signal_changed(struct wpa_supplicant *wpa_s,
|
||||
unsigned int id)
|
||||
{
|
||||
wpas_dbus_bss_signal_prop_changed(wpa_s, WPAS_DBUS_BSS_PROP_SIGNAL,
|
||||
id);
|
||||
}
|
||||
|
||||
|
||||
void wpas_notify_bss_privacy_changed(struct wpa_supplicant *wpa_s,
|
||||
unsigned int id)
|
||||
{
|
||||
wpas_dbus_bss_signal_prop_changed(wpa_s, WPAS_DBUS_BSS_PROP_PRIVACY,
|
||||
id);
|
||||
}
|
||||
|
||||
|
||||
void wpas_notify_bss_mode_changed(struct wpa_supplicant *wpa_s,
|
||||
unsigned int id)
|
||||
{
|
||||
wpas_dbus_bss_signal_prop_changed(wpa_s, WPAS_DBUS_BSS_PROP_MODE, id);
|
||||
}
|
||||
|
||||
|
||||
void wpas_notify_bss_wpaie_changed(struct wpa_supplicant *wpa_s,
|
||||
unsigned int id)
|
||||
{
|
||||
wpas_dbus_bss_signal_prop_changed(wpa_s, WPAS_DBUS_BSS_PROP_WPAIE, id);
|
||||
}
|
||||
|
||||
|
||||
void wpas_notify_bss_rsnie_changed(struct wpa_supplicant *wpa_s,
|
||||
unsigned int id)
|
||||
{
|
||||
wpas_dbus_bss_signal_prop_changed(wpa_s, WPAS_DBUS_BSS_PROP_RSNIE, id);
|
||||
}
|
||||
|
||||
|
||||
void wpas_notify_bss_wps_changed(struct wpa_supplicant *wpa_s,
|
||||
unsigned int id)
|
||||
{
|
||||
wpas_dbus_bss_signal_prop_changed(wpa_s, WPAS_DBUS_BSS_PROP_WPSIE, id);
|
||||
}
|
||||
|
||||
|
||||
void wpas_notify_bss_rates_changed(struct wpa_supplicant *wpa_s,
|
||||
unsigned int id)
|
||||
{
|
||||
wpas_dbus_bss_signal_prop_changed(wpa_s, WPAS_DBUS_BSS_PROP_RATES, id);
|
||||
}
|
||||
|
||||
|
||||
void wpas_notify_blob_added(struct wpa_supplicant *wpa_s, const char *name)
|
||||
{
|
||||
wpas_dbus_signal_blob_added(wpa_s, name);
|
||||
|
|
|
@ -51,6 +51,22 @@ void wpas_notify_bss_added(struct wpa_supplicant *wpa_s, u8 bssid[],
|
|||
unsigned int id);
|
||||
void wpas_notify_bss_removed(struct wpa_supplicant *wpa_s, u8 bssid[],
|
||||
unsigned int id);
|
||||
void wpas_notify_bss_freq_changed(struct wpa_supplicant *wpa_s,
|
||||
unsigned int id);
|
||||
void wpas_notify_bss_signal_changed(struct wpa_supplicant *wpa_s,
|
||||
unsigned int id);
|
||||
void wpas_notify_bss_privacy_changed(struct wpa_supplicant *wpa_s,
|
||||
unsigned int id);
|
||||
void wpas_notify_bss_mode_changed(struct wpa_supplicant *wpa_s,
|
||||
unsigned int id);
|
||||
void wpas_notify_bss_wpaie_changed(struct wpa_supplicant *wpa_s,
|
||||
unsigned int id);
|
||||
void wpas_notify_bss_rsnie_changed(struct wpa_supplicant *wpa_s,
|
||||
unsigned int id);
|
||||
void wpas_notify_bss_wps_changed(struct wpa_supplicant *wpa_s,
|
||||
unsigned int id);
|
||||
void wpas_notify_bss_rates_changed(struct wpa_supplicant *wpa_s,
|
||||
unsigned int id);
|
||||
void wpas_notify_blob_added(struct wpa_supplicant *wpa_s, const char *name);
|
||||
void wpas_notify_blob_removed(struct wpa_supplicant *wpa_s, const char *name);
|
||||
|
||||
|
|
Loading…
Reference in a new issue