diff --git a/src/device.c b/src/device.c index 445aec9f..f045cbee 100644 --- a/src/device.c +++ b/src/device.c @@ -25,11 +25,13 @@ #endif #include +#include #include #include "src/iwd.h" #include "src/common.h" +#include "src/util.h" #include "src/ie.h" #include "src/eapol.h" #include "src/wiphy.h" @@ -50,6 +52,8 @@ struct device_watchlist_item { static struct l_queue *device_watches = NULL; static uint32_t device_next_watch_id = 0; +static struct l_queue *device_list; + static void device_watchlist_item_free(void *userdata) { struct device_watchlist_item *item = userdata; @@ -123,6 +127,36 @@ void __device_watch_call_removed(struct device *device) } } +void __iwd_device_foreach(iwd_device_foreach_func func, void *user_data) +{ + const struct l_queue_entry *device_entry; + + for (device_entry = l_queue_get_entries(device_list); device_entry; + device_entry = device_entry->next) { + struct device *device = device_entry->data; + + func(device, user_data); + } +} + +static void bss_free(void *data) +{ + struct scan_bss *bss = data; + const char *addr; + + addr = util_address_to_string(bss->addr); + l_debug("Freeing BSS %s", addr); + + scan_bss_free(bss); +} + +static void network_free(void *data) +{ + struct network *network = data; + + network_remove(network, -ESHUTDOWN); +} + struct network *device_get_connected_network(struct device *device) { return device->connected_network; @@ -343,15 +377,89 @@ void device_connect_network(struct device *device, struct network *network, IWD_NETWORK_INTERFACE, "Connected"); } +struct device *device_create(struct wiphy *wiphy, struct netdev *netdev) +{ + struct device *device; + struct l_dbus *dbus = dbus_get_bus(); + uint32_t ifindex = netdev_get_ifindex(netdev); + + device = l_new(struct device, 1); + device->bss_list = l_queue_new(); + device->networks = l_hashmap_new(); + l_hashmap_set_hash_function(device->networks, l_str_hash); + l_hashmap_set_compare_function(device->networks, + (l_hashmap_compare_func_t) strcmp); + device->networks_sorted = l_queue_new(); + device->index = ifindex; + device->wiphy = wiphy; + device->netdev = netdev; + + l_queue_push_head(device_list, device); + + if (!l_dbus_object_add_interface(dbus, device_get_path(device), + IWD_DEVICE_INTERFACE, device)) + l_info("Unable to register %s interface", IWD_DEVICE_INTERFACE); + + __device_watch_call_added(device); + + scan_ifindex_add(device->index); + device_enter_state(device, DEVICE_STATE_AUTOCONNECT); + + return device; +} + +static void device_free(void *user) +{ + struct device *device = user; + struct l_dbus *dbus; + + l_debug(""); + + if (device->scan_pending) + dbus_pending_reply(&device->scan_pending, + dbus_error_aborted(device->scan_pending)); + + if (device->connect_pending) + dbus_pending_reply(&device->connect_pending, + dbus_error_aborted(device->connect_pending)); + + __device_watch_call_removed(device); + + dbus = dbus_get_bus(); + l_dbus_unregister_object(dbus, device_get_path(device)); + + l_queue_destroy(device->networks_sorted, NULL); + l_hashmap_destroy(device->networks, network_free); + + l_queue_destroy(device->bss_list, bss_free); + l_queue_destroy(device->old_bss_list, bss_free); + l_queue_destroy(device->autoconnect_list, l_free); + + scan_ifindex_remove(device->index); + l_free(device); +} + +void device_remove(struct device *device) +{ + if (!l_queue_remove(device_list, device)) + return; + + device_free(device); +} + bool device_init(void) { device_watches = l_queue_new(); + device_list = l_queue_new(); return true; } bool device_exit(void) { + l_queue_destroy(device_list, device_free); + device_list = NULL; + l_queue_destroy(device_watches, device_watchlist_item_free); return true; diff --git a/src/iwd.h b/src/iwd.h index f17ffae4..cc596657 100644 --- a/src/iwd.h +++ b/src/iwd.h @@ -22,9 +22,15 @@ #define uninitialized_var(x) x = x +struct device; + enum security { SECURITY_NONE, SECURITY_WEP, SECURITY_PSK, SECURITY_8021X, }; + +typedef void (*iwd_device_foreach_func)(struct device *, void *data); + +void __iwd_device_foreach(iwd_device_foreach_func func, void *user_data); diff --git a/src/wiphy.c b/src/wiphy.c index 8e65b207..bf4fcb76 100644 --- a/src/wiphy.c +++ b/src/wiphy.c @@ -68,7 +68,6 @@ struct autoconnect_entry { }; static struct l_queue *wiphy_list = NULL; -static struct l_queue *device_list; static bool new_scan_results(uint32_t wiphy_id, uint32_t ifindex, struct l_queue *bss_list, void *userdata); @@ -161,25 +160,6 @@ static void bss_free(void *data) scan_bss_free(bss); } -static void network_free(void *data) -{ - struct network *network = data; - - network_remove(network, -ESHUTDOWN); -} - -void __iwd_device_foreach(iwd_device_foreach_func func, void *user_data) -{ - const struct l_queue_entry *device_entry; - - for (device_entry = l_queue_get_entries(device_list); device_entry; - device_entry = device_entry->next) { - struct device *device = device_entry->data; - - func(device, user_data); - } -} - static void device_scan_triggered(int err, void *user_data) { struct device *device = user_data; @@ -600,76 +580,6 @@ static bool new_scan_results(uint32_t wiphy_id, uint32_t ifindex, return true; } -struct device *device_create(struct wiphy *wiphy, struct netdev *netdev) -{ - struct device *device; - struct l_dbus *dbus = dbus_get_bus(); - uint32_t ifindex = netdev_get_ifindex(netdev); - - device = l_new(struct device, 1); - device->bss_list = l_queue_new(); - device->networks = l_hashmap_new(); - l_hashmap_set_hash_function(device->networks, l_str_hash); - l_hashmap_set_compare_function(device->networks, - (l_hashmap_compare_func_t) strcmp); - device->networks_sorted = l_queue_new(); - device->index = ifindex; - device->wiphy = wiphy; - device->netdev = netdev; - - l_queue_push_head(device_list, device); - - if (!l_dbus_object_add_interface(dbus, device_get_path(device), - IWD_DEVICE_INTERFACE, device)) - l_info("Unable to register %s interface", IWD_DEVICE_INTERFACE); - - __device_watch_call_added(device); - - scan_ifindex_add(device->index); - device_enter_state(device, DEVICE_STATE_AUTOCONNECT); - - return device; -} - -static void device_free(void *user) -{ - struct device *device = user; - struct l_dbus *dbus; - - l_debug(""); - - if (device->scan_pending) - dbus_pending_reply(&device->scan_pending, - dbus_error_aborted(device->scan_pending)); - - if (device->connect_pending) - dbus_pending_reply(&device->connect_pending, - dbus_error_aborted(device->connect_pending)); - - __device_watch_call_removed(device); - - dbus = dbus_get_bus(); - l_dbus_unregister_object(dbus, device_get_path(device)); - - l_queue_destroy(device->networks_sorted, NULL); - l_hashmap_destroy(device->networks, network_free); - - l_queue_destroy(device->bss_list, bss_free); - l_queue_destroy(device->old_bss_list, bss_free); - l_queue_destroy(device->autoconnect_list, l_free); - - scan_ifindex_remove(device->index); - l_free(device); -} - -void device_remove(struct device *device) -{ - if (!l_queue_remove(device_list, device)) - return; - - device_free(device); -} - struct wiphy *wiphy_find(int wiphy_id) { return l_queue_find(wiphy_list, wiphy_match, L_UINT_TO_PTR(wiphy_id)); @@ -1055,7 +965,6 @@ bool wiphy_init(struct l_genl_family *in) l_error("Registering for regulatory notification failed"); wiphy_list = l_queue_new(); - device_list = l_queue_new(); msg = l_genl_msg_new(NL80211_CMD_GET_PROTOCOL_FEATURES); if (!l_genl_family_send(nl80211, msg, protocol_features_callback, @@ -1080,9 +989,6 @@ bool wiphy_exit(void) l_queue_destroy(wiphy_list, wiphy_free); wiphy_list = NULL; - l_queue_destroy(device_list, device_free); - device_list = NULL; - nl80211 = NULL; l_dbus_unregister_interface(dbus_get_bus(), IWD_DEVICE_INTERFACE); diff --git a/src/wiphy.h b/src/wiphy.h index 78763294..aeefb334 100644 --- a/src/wiphy.h +++ b/src/wiphy.h @@ -24,10 +24,6 @@ #include struct wiphy; -struct device; -struct netdev; - -typedef void (*iwd_device_foreach_func)(struct device *, void *data); enum ie_rsn_cipher_suite wiphy_select_cipher(struct wiphy *wiphy, uint16_t mask); @@ -36,5 +32,3 @@ struct wiphy *wiphy_find(int wiphy_id); bool wiphy_init(struct l_genl_family *in); bool wiphy_exit(void); - -void __iwd_device_foreach(iwd_device_foreach_func func, void *user_data);