diff --git a/src/wiphy.c b/src/wiphy.c index a53b770a..6286547c 100644 --- a/src/wiphy.c +++ b/src/wiphy.c @@ -45,6 +45,7 @@ #include "src/storage.h" #include "src/util.h" #include "src/common.h" +#include "src/watchlist.h" static struct l_genl_family *nl80211 = NULL; static struct l_hwdb *hwdb; @@ -62,6 +63,7 @@ struct wiphy { struct scan_freq_set *supported_freqs; char *model_str; char *vendor_str; + struct watchlist state_watches; bool support_scheduled_scan:1; bool support_rekey_offload:1; @@ -154,6 +156,7 @@ static struct wiphy *wiphy_new(uint32_t id) wiphy->id = id; wiphy->supported_freqs = scan_freq_set_new(); + watchlist_init(&wiphy->state_watches, NULL); return wiphy; } @@ -165,6 +168,7 @@ static void wiphy_free(void *data) l_debug("Freeing wiphy %s[%u]", wiphy->name, wiphy->id); scan_freq_set_free(wiphy->supported_freqs); + watchlist_destroy(&wiphy->state_watches); l_free(wiphy->model_str); l_free(wiphy->vendor_str); l_free(wiphy); @@ -312,6 +316,18 @@ bool wiphy_supports_iftype(struct wiphy *wiphy, uint32_t iftype) return wiphy->supported_iftypes & (1 << (iftype - 1)); } +uint32_t wiphy_state_watch_add(struct wiphy *wiphy, + wiphy_state_watch_func_t func, + void *user_data, wiphy_destroy_func_t destroy) +{ + return watchlist_add(&wiphy->state_watches, func, user_data, destroy); +} + +bool wiphy_state_watch_remove(struct wiphy *wiphy, uint32_t id) +{ + return watchlist_remove(&wiphy->state_watches, id); +} + static void wiphy_print_basic_info(struct wiphy *wiphy) { uint32_t bands; @@ -867,6 +883,7 @@ static void wiphy_rfkill_cb(unsigned int wiphy_id, bool soft, bool hard, struct wiphy *wiphy = wiphy_find(wiphy_id); struct l_dbus *dbus = dbus_get_bus(); bool old_powered, new_powered; + enum wiphy_state_watch_event event; if (!wiphy) return; @@ -878,8 +895,15 @@ static void wiphy_rfkill_cb(unsigned int wiphy_id, bool soft, bool hard, new_powered = !wiphy->soft_rfkill && !wiphy->hard_rfkill; - if (old_powered != new_powered) - l_dbus_property_changed(dbus, wiphy_get_path(wiphy), + if (old_powered == new_powered) + return; + + event = new_powered ? WIPHY_STATE_WATCH_EVENT_POWERED : + WIPHY_STATE_WATCH_EVENT_RFKILLED; + WATCHLIST_NOTIFY(&wiphy->state_watches, wiphy_state_watch_func_t, + wiphy, event); + + l_dbus_property_changed(dbus, wiphy_get_path(wiphy), IWD_WIPHY_INTERFACE, "Powered"); } diff --git a/src/wiphy.h b/src/wiphy.h index af2baee9..12e5a78e 100644 --- a/src/wiphy.h +++ b/src/wiphy.h @@ -26,6 +26,16 @@ struct wiphy; struct scan_bss; +enum wiphy_state_watch_event { + WIPHY_STATE_WATCH_EVENT_POWERED, + WIPHY_STATE_WATCH_EVENT_RFKILLED, +}; + +typedef void (*wiphy_state_watch_func_t)(struct wiphy *wiphy, + enum wiphy_state_watch_event event, + void *user_data); +typedef void (*wiphy_destroy_func_t)(void *user_data); + enum ie_rsn_cipher_suite wiphy_select_cipher(struct wiphy *wiphy, uint16_t mask); enum ie_rsn_akm_suite wiphy_select_akm(struct wiphy *wiphy, @@ -42,6 +52,11 @@ uint8_t wiphy_get_max_num_ssids_per_scan(struct wiphy *wiphy); bool wiphy_supports_iftype(struct wiphy *wiphy, uint32_t iftype); bool wiphy_supports_adhoc_rsn(struct wiphy *wiphy); +uint32_t wiphy_state_watch_add(struct wiphy *wiphy, + wiphy_state_watch_func_t func, void *user_data, + wiphy_destroy_func_t destroy); +bool wiphy_state_watch_remove(struct wiphy *wiphy, uint32_t id); + bool wiphy_init(struct l_genl_family *in, const char *whitelist, const char *blacklist); bool wiphy_exit(void);