From b49ec9461b2cafc5707a7e42a9c21ebb257ac33b Mon Sep 17 00:00:00 2001 From: Denis Kenzior Date: Tue, 4 Sep 2018 17:32:18 -0500 Subject: [PATCH] station: move the remaining scanning code from device --- src/device.c | 148 +------------------------------------------------- src/station.c | 145 ++++++++++++++++++++++++++++++++++++++++++++++++- src/station.h | 13 ++--- 3 files changed, 152 insertions(+), 154 deletions(-) diff --git a/src/device.c b/src/device.c index 95c93890..4ff03404 100644 --- a/src/device.c +++ b/src/device.c @@ -49,7 +49,6 @@ struct device { uint32_t index; - struct l_dbus_message *scan_pending; struct l_dbus_message *connect_pending; struct l_dbus_message *disconnect_pending; uint8_t preauth_bssid[ETH_ALEN]; @@ -60,7 +59,6 @@ struct device { struct station *station; bool powered : 1; - bool scanning : 1; bool autoconnect : 1; uint32_t ap_roam_watch; @@ -77,36 +75,6 @@ static uint32_t netdev_watch; static void device_netdev_event(struct netdev *netdev, enum netdev_event event, void *user_data); -static bool new_scan_results(uint32_t wiphy_id, uint32_t ifindex, int err, - struct l_queue *bss_list, void *userdata) -{ - struct device *device = userdata; - struct station *station = device->station; - struct l_dbus *dbus = dbus_get_bus(); - bool autoconnect; - - if (device->scanning) { - device->scanning = false; - l_dbus_property_changed(dbus, netdev_get_path(device->netdev), - IWD_DEVICE_INTERFACE, "Scanning"); - } - - if (err) - return false; - - /* TODO: Remove when Device/Station split is done */ - if (netdev_get_iftype(device->netdev) != NETDEV_IFTYPE_STATION) - return false; - - autoconnect = station_get_state(station) == STATION_STATE_AUTOCONNECT; - station_set_scan_results(station, bss_list, autoconnect); - - if (autoconnect) - station_autoconnect_next(station); - - return true; -} - /* TODO: Remove when Station/Device is split */ static bool device_is_busy(struct device *device) { @@ -116,29 +84,6 @@ static bool device_is_busy(struct device *device) return station_is_busy(device->station); } -static void periodic_scan_trigger(int err, void *user_data) -{ - struct device *device = user_data; - struct l_dbus *dbus = dbus_get_bus(); - - device->scanning = true; - l_dbus_property_changed(dbus, netdev_get_path(device->netdev), - IWD_DEVICE_INTERFACE, "Scanning"); -} - -static void periodic_scan_stop(struct device *device) -{ - struct l_dbus *dbus = dbus_get_bus(); - - scan_periodic_stop(device->index); - - if (device->scanning) { - device->scanning = false; - l_dbus_property_changed(dbus, netdev_get_path(device->netdev), - IWD_DEVICE_INTERFACE, "Scanning"); - } -} - static void device_enter_state(struct device *device, enum station_state state) { struct station *station = device->station; @@ -149,25 +94,6 @@ static void device_enter_state(struct device *device, enum station_state state) station_state_to_string(station->state), station_state_to_string(state)); - switch (state) { - case STATION_STATE_AUTOCONNECT: - scan_periodic_start(device->index, periodic_scan_trigger, - new_scan_results, device); - break; - case STATION_STATE_DISCONNECTED: - periodic_scan_stop(device); - break; - case STATION_STATE_CONNECTED: - periodic_scan_stop(device); - break; - case STATION_STATE_CONNECTING: - break; - case STATION_STATE_DISCONNECTING: - break; - case STATION_STATE_ROAMING: - break; - } - disconnected = station->state <= STATION_STATE_AUTOCONNECT; if ((disconnected && state > STATION_STATE_AUTOCONNECT) || @@ -640,34 +566,6 @@ void device_connect_network(struct device *device, struct network *network, device->autoconnect = true; } -static void device_scan_triggered(int err, void *user_data) -{ - struct device *device = user_data; - struct l_dbus_message *reply; - struct l_dbus *dbus = dbus_get_bus(); - - l_debug("device_scan_triggered: %i", err); - - if (!device->scan_pending) - return; - - if (err < 0) { - dbus_pending_reply(&device->scan_pending, - dbus_error_failed(device->scan_pending)); - return; - } - - l_debug("Scan triggered for %s", netdev_get_name(device->netdev)); - - device->scanning = true; - l_dbus_property_changed(dbus, netdev_get_path(device->netdev), - IWD_DEVICE_INTERFACE, "Scanning"); - - reply = l_dbus_message_new_method_return(device->scan_pending); - l_dbus_message_set_arguments(reply, ""); - dbus_pending_reply(&device->scan_pending, reply); -} - static struct l_dbus_message *device_scan(struct l_dbus *dbus, struct l_dbus_message *message, void *user_data) @@ -675,11 +573,6 @@ static struct l_dbus_message *device_scan(struct l_dbus *dbus, struct device *device = user_data; struct station *station = device->station; - l_debug("Scan called from DBus"); - - if (device->scan_pending) - return dbus_error_busy(message); - /* TODO: Remove when Device/Station split is done */ if (netdev_get_iftype(device->netdev) != NETDEV_IFTYPE_STATION) return dbus_error_not_available(message); @@ -687,34 +580,7 @@ static struct l_dbus_message *device_scan(struct l_dbus *dbus, if (!device->powered) return dbus_error_failed(message); - device->scan_pending = l_dbus_message_ref(message); - - /* - * If we're not connected and no hidden networks are seen & configured, - * use passive scanning to hide our MAC address - */ - if (!station->connected_bss && - !(device->station->seen_hidden_networks && - known_networks_has_hidden())) { - if (!scan_passive(device->index, device_scan_triggered, - new_scan_results, device, NULL)) - return dbus_error_failed(message); - } else { - struct scan_parameters params; - - memset(¶ms, 0, sizeof(params)); - - /* If we're connected, HW cannot randomize our MAC */ - if (!station->connected_bss) - params.randomize_mac_addr_hint = true; - - if (!scan_active_full(device->index, ¶ms, - device_scan_triggered, - new_scan_results, device, NULL)) - return dbus_error_failed(message); - } - - return NULL; + return station_dbus_scan(dbus, message, station); } static void device_disconnect_cb(struct netdev *netdev, bool success, @@ -1269,7 +1135,8 @@ static bool device_property_get_scanning(struct l_dbus *dbus, void *user_data) { struct device *device = user_data; - bool scanning = device->scanning; + struct station *station = device->station; + bool scanning = station->scanning; l_dbus_message_builder_append_basic(builder, 'b', &scanning); @@ -1484,11 +1351,6 @@ static void device_netdev_notify(struct netdev *netdev, } device->powered = false; - periodic_scan_stop(device); - - 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, @@ -1560,10 +1422,6 @@ void device_remove(struct device *device) 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)); diff --git a/src/station.c b/src/station.c index 6240b760..33c75475 100644 --- a/src/station.c +++ b/src/station.c @@ -38,8 +38,10 @@ #include "src/watchlist.h" #include "src/scan.h" #include "src/netdev.h" +#include "src/dbus.h" #include "src/wiphy.h" #include "src/network.h" +#include "src/knownnetworks.h" #include "src/ie.h" #include "src/handshake.h" #include "src/station.h" @@ -76,7 +78,7 @@ struct autoconnect_entry { struct scan_bss *bss; }; -void station_autoconnect_next(struct station *station) +static void station_autoconnect_next(struct station *station) { struct autoconnect_entry *entry; int r; @@ -106,7 +108,7 @@ static int autoconnect_rank_compare(const void *a, const void *b, void *user) return ae->rank - new_ae->rank; } -void station_add_autoconnect_bss(struct station *station, +static void station_add_autoconnect_bss(struct station *station, struct network *network, struct scan_bss *bss) { @@ -525,6 +527,55 @@ not_supported: return NULL; } +static bool new_scan_results(uint32_t wiphy_id, uint32_t ifindex, int err, + struct l_queue *bss_list, void *userdata) +{ + struct station *station = userdata; + struct l_dbus *dbus = dbus_get_bus(); + bool autoconnect; + + if (station->scanning) { + station->scanning = false; + l_dbus_property_changed(dbus, netdev_get_path(station->netdev), + IWD_DEVICE_INTERFACE, "Scanning"); + } + + if (err) + return false; + + autoconnect = station_get_state(station) == STATION_STATE_AUTOCONNECT; + station_set_scan_results(station, bss_list, autoconnect); + + if (autoconnect) + station_autoconnect_next(station); + + return true; +} + +static void periodic_scan_trigger(int err, void *user_data) +{ + struct station *station = user_data; + struct l_dbus *dbus = dbus_get_bus(); + + station->scanning = true; + l_dbus_property_changed(dbus, netdev_get_path(station->netdev), + IWD_DEVICE_INTERFACE, "Scanning"); +} + +static void periodic_scan_stop(struct station *station) +{ + struct l_dbus *dbus = dbus_get_bus(); + uint32_t index = netdev_get_ifindex(station->netdev); + + scan_periodic_stop(index); + + if (station->scanning) { + station->scanning = false; + l_dbus_property_changed(dbus, netdev_get_path(station->netdev), + IWD_DEVICE_INTERFACE, "Scanning"); + } +} + const char *station_state_to_string(enum station_state state) { switch (state) { @@ -547,6 +598,23 @@ const char *station_state_to_string(enum station_state state) void station_enter_state(struct station *station, enum station_state state) { + uint32_t index = netdev_get_ifindex(station->netdev); + + switch (state) { + case STATION_STATE_AUTOCONNECT: + scan_periodic_start(index, periodic_scan_trigger, + new_scan_results, station); + break; + case STATION_STATE_DISCONNECTED: + case STATION_STATE_CONNECTED: + case STATION_STATE_CONNECTING: + periodic_scan_stop(station); + break; + case STATION_STATE_DISCONNECTING: + case STATION_STATE_ROAMING: + break; + } + station->state = state; WATCHLIST_NOTIFY(&station->state_watches, @@ -1135,6 +1203,73 @@ void station_ok_rssi(struct station *station) station->signal_low = false; } +static void station_dbus_scan_triggered(int err, void *user_data) +{ + struct station *station = user_data; + struct l_dbus_message *reply; + struct l_dbus *dbus = dbus_get_bus(); + + l_debug("station_scan_triggered: %i", err); + + if (err < 0) { + reply = dbus_error_from_errno(err, station->scan_pending); + dbus_pending_reply(&station->scan_pending, reply); + return; + } + + l_debug("Scan triggered for %s", netdev_get_name(station->netdev)); + + reply = l_dbus_message_new_method_return(station->scan_pending); + l_dbus_message_set_arguments(reply, ""); + dbus_pending_reply(&station->scan_pending, reply); + + station->scanning = true; + l_dbus_property_changed(dbus, netdev_get_path(station->netdev), + IWD_DEVICE_INTERFACE, "Scanning"); +} + +struct l_dbus_message *station_dbus_scan(struct l_dbus *dbus, + struct l_dbus_message *message, + void *user_data) +{ + struct station *station = user_data; + uint32_t index = netdev_get_ifindex(station->netdev); + + l_debug("Scan called from DBus"); + + if (station->scan_pending) + return dbus_error_busy(message); + + station->scan_pending = l_dbus_message_ref(message); + + /* + * If we're not connected and no hidden networks are seen & configured, + * use passive scanning to hide our MAC address + */ + if (!station->connected_bss && + !(station->seen_hidden_networks && + known_networks_has_hidden())) { + if (!scan_passive(index, station_dbus_scan_triggered, + new_scan_results, station, NULL)) + return dbus_error_failed(message); + } else { + struct scan_parameters params; + + memset(¶ms, 0, sizeof(params)); + + /* If we're connected, HW cannot randomize our MAC */ + if (!station->connected_bss) + params.randomize_mac_addr_hint = true; + + if (!scan_active_full(index, ¶ms, + station_dbus_scan_triggered, + new_scan_results, station, NULL)) + return dbus_error_failed(message); + } + + return NULL; +} + void station_foreach(station_foreach_func_t func, void *user_data) { const struct l_queue_entry *entry; @@ -1191,6 +1326,12 @@ void station_free(struct station *station) if (!l_queue_remove(station_list, station)) return; + periodic_scan_stop(station); + + if (station->scan_pending) + dbus_pending_reply(&station->scan_pending, + dbus_error_aborted(station->scan_pending)); + l_timeout_remove(station->roam_trigger_timeout); l_queue_destroy(station->networks_sorted, NULL); diff --git a/src/station.h b/src/station.h index c24f7e9d..e4d4199f 100644 --- a/src/station.h +++ b/src/station.h @@ -51,6 +51,7 @@ struct station { struct l_queue *bss_list; struct l_hashmap *networks; struct l_queue *networks_sorted; + struct l_dbus_message *scan_pending; /* Roaming related members */ struct timespec roam_min_time; @@ -65,6 +66,7 @@ struct station { bool signal_low : 1; bool roam_no_orig_ap : 1; bool ap_directed_roaming : 1; + bool scanning : 1; }; struct wiphy *station_get_wiphy(struct station *station); @@ -72,11 +74,6 @@ struct netdev *station_get_netdev(struct station *station); struct network *station_get_connected_network(struct station *station); bool station_is_busy(struct station *station); -void station_autoconnect_next(struct station *station); -void station_add_autoconnect_bss(struct station *station, - struct network *network, - struct scan_bss *bss); - struct network *station_network_find(struct station *station, const char *ssid, enum security security); @@ -110,9 +107,11 @@ void station_ap_directed_roam(struct station *station, void station_low_rssi(struct station *station); void station_ok_rssi(struct station *station); +struct l_dbus_message *station_dbus_scan(struct l_dbus *dbus, + struct l_dbus_message *message, + void *user_data); + struct station *station_find(uint32_t ifindex); - - void station_foreach(station_foreach_func_t func, void *user_data); struct station *station_create(struct wiphy *wiphy, struct netdev *netdev); void station_free(struct station *station);