From e028b7019c5a21eef38a879fc30e12e798928855 Mon Sep 17 00:00:00 2001 From: Denis Kenzior Date: Tue, 4 Sep 2018 10:40:45 -0500 Subject: [PATCH] station: Move state tracking from device --- src/device.c | 221 +++++++++++++++++++++----------------------------- src/device.h | 20 ----- src/station.c | 50 ++++++++++++ src/station.h | 23 ++++++ src/wsc.c | 85 +++++++++++-------- 5 files changed, 218 insertions(+), 181 deletions(-) diff --git a/src/device.c b/src/device.c index 06526a62..bd177288 100644 --- a/src/device.c +++ b/src/device.c @@ -50,13 +50,11 @@ struct device { uint32_t index; - enum device_state state; struct l_dbus_message *scan_pending; struct scan_bss *connected_bss; struct network *connected_network; struct l_dbus_message *connect_pending; struct l_dbus_message *disconnect_pending; - struct watchlist state_watches; struct timespec roam_min_time; struct l_timeout *roam_trigger_timeout; uint32_t roam_scan_id; @@ -67,6 +65,7 @@ struct device { struct netdev *netdev; struct station *station; + bool powered : 1; bool scanning : 1; bool autoconnect : 1; bool preparing_roam : 1; @@ -103,28 +102,6 @@ void __iwd_device_foreach(iwd_device_foreach_func func, void *user_data) } } -static const char *device_state_to_string(enum device_state state) -{ - switch (state) { - case DEVICE_STATE_OFF: - return "off"; - case DEVICE_STATE_DISCONNECTED: - return "disconnected"; - case DEVICE_STATE_AUTOCONNECT: - return "autoconnect"; - case DEVICE_STATE_CONNECTING: - return "connecting"; - case DEVICE_STATE_CONNECTED: - return "connected"; - case DEVICE_STATE_DISCONNECTING: - return "disconnecting"; - case DEVICE_STATE_ROAMING: - return "roaming"; - } - - return "invalid"; -} - void device_set_scan_results(struct device *device, struct l_queue *bss_list, bool add_to_autoconnect) { @@ -136,7 +113,7 @@ static bool new_scan_results(uint32_t wiphy_id, uint32_t ifindex, int err, { struct device *device = userdata; struct l_dbus *dbus = dbus_get_bus(); - bool autoconnect = device->state == DEVICE_STATE_AUTOCONNECT; + bool autoconnect; if (device->scanning) { device->scanning = false; @@ -151,6 +128,8 @@ static bool new_scan_results(uint32_t wiphy_id, uint32_t ifindex, int err, if (netdev_get_iftype(device->netdev) != NETDEV_IFTYPE_STATION) return false; + autoconnect = station_get_state(device->station) == + STATION_STATE_AUTOCONNECT; device_set_scan_results(device, bss_list, autoconnect); if (autoconnect) @@ -173,11 +152,17 @@ const char *device_get_path(struct device *device) return path; } +/* TODO: Remove when Station/Device is split */ bool device_is_busy(struct device *device) { - if (device->state != DEVICE_STATE_DISCONNECTED && - device->state != DEVICE_STATE_AUTOCONNECT && - device->state != DEVICE_STATE_OFF) + enum station_state state; + + if (!device->powered || !device->station) + return false; + + state = station_get_state(device->station); + if (state != STATION_STATE_DISCONNECTED && + state != STATION_STATE_AUTOCONNECT) return true; return false; @@ -188,11 +173,6 @@ struct wiphy *device_get_wiphy(struct device *device) return device->wiphy; } -enum device_state device_get_state(struct device *device) -{ - return device->state; -} - static void periodic_scan_trigger(int err, void *user_data) { struct device *device = user_data; @@ -216,67 +196,49 @@ static void periodic_scan_stop(struct device *device) } } -uint32_t device_add_state_watch(struct device *device, - device_state_watch_func_t func, - void *user_data, - device_destroy_func_t destroy) -{ - return watchlist_add(&device->state_watches, func, user_data, destroy); -} - -bool device_remove_state_watch(struct device *device, uint32_t id) -{ - return watchlist_remove(&device->state_watches, id); -} - struct network *device_network_find(struct device *device, const char *ssid, enum security security) { return station_network_find(device->station, ssid, security); } -static void device_enter_state(struct device *device, enum device_state state) +static void device_enter_state(struct device *device, enum station_state state) { + struct station *station = device->station; struct l_dbus *dbus = dbus_get_bus(); bool disconnected; l_debug("Old State: %s, new state: %s", - device_state_to_string(device->state), - device_state_to_string(state)); + station_state_to_string(station->state), + station_state_to_string(state)); switch (state) { - case DEVICE_STATE_OFF: - periodic_scan_stop(device); - break; - case DEVICE_STATE_AUTOCONNECT: + case STATION_STATE_AUTOCONNECT: scan_periodic_start(device->index, periodic_scan_trigger, new_scan_results, device); break; - case DEVICE_STATE_DISCONNECTED: + case STATION_STATE_DISCONNECTED: periodic_scan_stop(device); break; - case DEVICE_STATE_CONNECTED: + case STATION_STATE_CONNECTED: periodic_scan_stop(device); break; - case DEVICE_STATE_CONNECTING: + case STATION_STATE_CONNECTING: break; - case DEVICE_STATE_DISCONNECTING: + case STATION_STATE_DISCONNECTING: break; - case DEVICE_STATE_ROAMING: + case STATION_STATE_ROAMING: break; } - disconnected = device->state <= DEVICE_STATE_AUTOCONNECT; + disconnected = station->state <= STATION_STATE_AUTOCONNECT; - if ((disconnected && state > DEVICE_STATE_AUTOCONNECT) || - (!disconnected && state != device->state)) + if ((disconnected && state > STATION_STATE_AUTOCONNECT) || + (!disconnected && state != station->state)) l_dbus_property_changed(dbus, device_get_path(device), IWD_DEVICE_INTERFACE, "State"); - device->state = state; - - WATCHLIST_NOTIFY(&device->state_watches, - device_state_watch_func_t, state); + station_enter_state(station, state); } static void device_reset_connection_state(struct device *device) @@ -288,9 +250,9 @@ static void device_reset_connection_state(struct device *device) if (!network) return; - if (device->state == DEVICE_STATE_CONNECTED || - device->state == DEVICE_STATE_CONNECTING || - device->state == DEVICE_STATE_ROAMING) + if (station->state == STATION_STATE_CONNECTED || + station->state == STATION_STATE_CONNECTING || + station->state == STATION_STATE_ROAMING) network_disconnected(network); l_timeout_remove(device->roam_trigger_timeout); @@ -319,10 +281,10 @@ static void device_disassociated(struct device *device) device_reset_connection_state(device); - device_enter_state(device, DEVICE_STATE_DISCONNECTED); + device_enter_state(device, STATION_STATE_DISCONNECTED); if (device->autoconnect) - device_enter_state(device, DEVICE_STATE_AUTOCONNECT); + device_enter_state(device, STATION_STATE_AUTOCONNECT); } static void device_disconnect_event(struct device *device) @@ -343,6 +305,8 @@ static void device_disconnect_event(struct device *device) static void device_roam_failed(struct device *device) { + struct station *station = device->station; + /* * If we're still connected to the old BSS, only clear preparing_roam * and reattempt in 60 seconds if signal level is still low at that @@ -357,7 +321,7 @@ static void device_roam_failed(struct device *device) device->roam_no_orig_ap = false; device->ap_directed_roaming = false; - if (device->state == DEVICE_STATE_ROAMING) + if (station->state == STATION_STATE_ROAMING) device_disassociated(device); else if (device->signal_low) device_roam_timeout_rearm(device, 60); @@ -368,10 +332,11 @@ static void device_reassociate_cb(struct netdev *netdev, void *user_data) { struct device *device = user_data; + struct station *station = device->station; l_debug("%d, result: %d", device->index, result); - if (device->state != DEVICE_STATE_ROAMING) + if (station->state != STATION_STATE_ROAMING) return; if (result == NETDEV_RESULT_OK) { @@ -383,7 +348,7 @@ static void device_reassociate_cb(struct netdev *netdev, device->roam_min_time.tv_sec = 0; device->roam_no_orig_ap = false; - device_enter_state(device, DEVICE_STATE_CONNECTED); + device_enter_state(device, STATION_STATE_CONNECTED); } else device_roam_failed(device); } @@ -393,10 +358,11 @@ static void device_fast_transition_cb(struct netdev *netdev, void *user_data) { struct device *device = user_data; + struct station *station = device->station; l_debug("%d, result: %d", device->index, result); - if (device->state != DEVICE_STATE_ROAMING) + if (station->state != STATION_STATE_ROAMING) return; if (result == NETDEV_RESULT_OK) { @@ -408,7 +374,7 @@ static void device_fast_transition_cb(struct netdev *netdev, device->roam_min_time.tv_sec = 0; device->roam_no_orig_ap = false; - device_enter_state(device, DEVICE_STATE_CONNECTED); + device_enter_state(device, STATION_STATE_CONNECTED); } else device_roam_failed(device); } @@ -431,7 +397,7 @@ static void device_transition_reassociate(struct device *device, device->connected_bss = bss; station->connected_bss = bss; device->preparing_roam = false; - device_enter_state(device, DEVICE_STATE_ROAMING); + device_enter_state(device, STATION_STATE_ROAMING); } static bool bss_match_bssid(const void *a, const void *b) @@ -549,7 +515,7 @@ static void device_transition_start(struct device *device, struct scan_bss *bss) device->connected_bss = bss; station->connected_bss = bss; device->preparing_roam = false; - device_enter_state(device, DEVICE_STATE_ROAMING); + device_enter_state(device, STATION_STATE_ROAMING); return; } @@ -991,12 +957,13 @@ static void device_ap_roam_frame_event(struct netdev *netdev, void *user_data) { struct device *device = user_data; + struct station *station = device->station; uint32_t pos = 0; uint8_t req_mode; uint16_t dtimer; uint8_t valid_interval; - if (device->preparing_roam || device->state == DEVICE_STATE_ROAMING) + if (device->preparing_roam || station->state == STATION_STATE_ROAMING) return; if (body_len < 7) @@ -1068,10 +1035,12 @@ format_error: static void device_lost_beacon(struct device *device) { + struct station *station = device->station; + l_debug("%d", device->index); - if (device->state != DEVICE_STATE_ROAMING && - device->state != DEVICE_STATE_CONNECTED) + if (station->state != STATION_STATE_ROAMING && + station->state != STATION_STATE_CONNECTED) return; /* @@ -1083,7 +1052,7 @@ static void device_lost_beacon(struct device *device) */ device->roam_no_orig_ap = true; - if (device->preparing_roam || device->state == DEVICE_STATE_ROAMING) + if (device->preparing_roam || station->state == STATION_STATE_ROAMING) return; device_roam_trigger_cb(NULL, device); @@ -1126,7 +1095,7 @@ static void device_connect_cb(struct netdev *netdev, enum netdev_result result, } network_connected(device->connected_network); - device_enter_state(device, DEVICE_STATE_CONNECTED); + device_enter_state(device, STATION_STATE_CONNECTED); } static void device_signal_agent_notify(struct signal_agent *agent, @@ -1164,6 +1133,7 @@ static void device_netdev_event(struct netdev *netdev, enum netdev_event event, void *user_data) { struct device *device = user_data; + struct station *station = device->station; switch (event) { case NETDEV_EVENT_AUTHENTICATING: @@ -1186,7 +1156,7 @@ static void device_netdev_event(struct netdev *netdev, enum netdev_event event, device->signal_low = true; if (device->preparing_roam || - device->state == DEVICE_STATE_ROAMING) + station->state == STATION_STATE_ROAMING) break; /* Set a 5-second initial timeout */ @@ -1212,16 +1182,18 @@ static void device_netdev_event(struct netdev *netdev, enum netdev_event event, bool device_set_autoconnect(struct device *device, bool autoconnect) { + struct station *station = device->station; + if (device->autoconnect == autoconnect) return true; device->autoconnect = autoconnect; - if (device->state == DEVICE_STATE_DISCONNECTED && autoconnect) - device_enter_state(device, DEVICE_STATE_AUTOCONNECT); + if (station->state == STATION_STATE_DISCONNECTED && autoconnect) + device_enter_state(device, STATION_STATE_AUTOCONNECT); - if (device->state == DEVICE_STATE_AUTOCONNECT && !autoconnect) - device_enter_state(device, DEVICE_STATE_DISCONNECTED); + if (station->state == STATION_STATE_AUTOCONNECT && !autoconnect) + device_enter_state(device, STATION_STATE_DISCONNECTED); return true; } @@ -1253,7 +1225,7 @@ int __device_connect_network(struct device *device, struct network *network, device->connected_network = network; station->connected_network = network; - device_enter_state(device, DEVICE_STATE_CONNECTING); + device_enter_state(device, STATION_STATE_CONNECTING); l_dbus_property_changed(dbus, device_get_path(device), IWD_DEVICE_INTERFACE, "ConnectedNetwork"); @@ -1323,7 +1295,7 @@ static struct l_dbus_message *device_scan(struct l_dbus *dbus, if (netdev_get_iftype(device->netdev) != NETDEV_IFTYPE_STATION) return dbus_error_not_available(message); - if (device->state == DEVICE_STATE_OFF) + if (!device->powered) return dbus_error_failed(message); device->scan_pending = l_dbus_message_ref(message); @@ -1378,18 +1350,20 @@ static void device_disconnect_cb(struct netdev *netdev, bool success, } - device_enter_state(device, DEVICE_STATE_DISCONNECTED); + device_enter_state(device, STATION_STATE_DISCONNECTED); if (device->autoconnect) - device_enter_state(device, DEVICE_STATE_AUTOCONNECT); + device_enter_state(device, STATION_STATE_AUTOCONNECT); } int device_disconnect(struct device *device) { - if (device->state == DEVICE_STATE_DISCONNECTING) + struct station *station = device->station; + + if (station->state == STATION_STATE_DISCONNECTING) return -EBUSY; - if (!device->connected_bss) + if (!station->connected_bss) return -ENOTCONN; if (netdev_disconnect(device->netdev, device_disconnect_cb, device) < 0) @@ -1402,7 +1376,7 @@ int device_disconnect(struct device *device) */ device_reset_connection_state(device); - device_enter_state(device, DEVICE_STATE_DISCONNECTING); + device_enter_state(device, STATION_STATE_DISCONNECTING); return 0; } @@ -1412,6 +1386,7 @@ static struct l_dbus_message *device_dbus_disconnect(struct l_dbus *dbus, void *user_data) { struct device *device = user_data; + struct station *station = device->station; int result; l_debug(""); @@ -1422,8 +1397,8 @@ static struct l_dbus_message *device_dbus_disconnect(struct l_dbus *dbus, */ device_set_autoconnect(device, false); - if (device->state == DEVICE_STATE_AUTOCONNECT || - device->state == DEVICE_STATE_DISCONNECTED) + if (station->state == STATION_STATE_AUTOCONNECT || + station->state == STATION_STATE_DISCONNECTED) return l_dbus_message_new_method_return(message); result = device_disconnect(device); @@ -1680,7 +1655,7 @@ static struct l_dbus_message *device_connect_hidden_network(struct l_dbus *dbus, l_debug(""); - if (device->state == DEVICE_STATE_OFF) + if (!device->powered) return dbus_error_failed(message); if (device->connect_pending || device_is_busy(device)) @@ -1760,7 +1735,7 @@ static bool device_property_get_powered(struct l_dbus *dbus, void *user_data) { struct device *device = user_data; - bool powered = device->state != DEVICE_STATE_OFF; + bool powered = device->powered; l_dbus_message_builder_append_basic(builder, 'b', &powered); @@ -1812,7 +1787,7 @@ static struct l_dbus_message *device_property_set_powered(struct l_dbus *dbus, if (!l_dbus_message_iter_get_variant(new_value, "b", &powered)) return dbus_error_invalid_args(message); - if (powered == (device->state != DEVICE_STATE_OFF)) { + if (powered == device->powered) { complete(dbus, message, NULL); return NULL; @@ -1913,7 +1888,7 @@ static bool device_property_get_state(struct l_dbus *dbus, void *user_data) { struct device *device = user_data; - const char *statestr = "unknown"; + const char *statestr; /* TODO: Remove when Device/Station split is done */ if (netdev_get_iftype(device->netdev) != NETDEV_IFTYPE_STATION) { @@ -1923,28 +1898,19 @@ static bool device_property_get_state(struct l_dbus *dbus, return true; } - switch (device->state) { - case DEVICE_STATE_CONNECTED: - statestr = "connected"; - break; - case DEVICE_STATE_CONNECTING: - statestr = "connecting"; - break; - case DEVICE_STATE_DISCONNECTING: - statestr = "disconnecting"; - break; - case DEVICE_STATE_OFF: - case DEVICE_STATE_DISCONNECTED: - case DEVICE_STATE_AUTOCONNECT: - statestr = "disconnected"; - break; - case DEVICE_STATE_ROAMING: - statestr = "roaming"; - break; + if (device->powered == false) { + l_dbus_message_builder_append_basic(builder, + 's', "disconnected"); + return true; } - l_dbus_message_builder_append_basic(builder, 's', statestr); + statestr = station_state_to_string(device->station->state); + /* Special case. For now we treat AUTOCONNECT as disconnected */ + if (device->station->state == STATION_STATE_AUTOCONNECT) + statestr = "disconnected"; + + l_dbus_message_builder_append_basic(builder, 's', statestr); return true; } @@ -2100,6 +2066,7 @@ static void device_netdev_notify(struct netdev *netdev, switch (event) { case NETDEV_WATCH_EVENT_UP: + device->powered = true; l_dbus_property_changed(dbus, device_get_path(device), IWD_DEVICE_INTERFACE, "Powered"); @@ -2110,9 +2077,9 @@ static void device_netdev_notify(struct netdev *netdev, device->station = station_create(device->wiphy, device->netdev); if (device->autoconnect) - device_enter_state(device, DEVICE_STATE_AUTOCONNECT); + device_enter_state(device, STATION_STATE_AUTOCONNECT); else - device_enter_state(device, DEVICE_STATE_DISCONNECTED); + device_enter_state(device, STATION_STATE_DISCONNECTED); break; case NETDEV_WATCH_EVENT_DOWN: if (device->station) { @@ -2120,7 +2087,8 @@ static void device_netdev_notify(struct netdev *netdev, device->station = NULL; } - device_enter_state(device, DEVICE_STATE_OFF); + device->powered = false; + periodic_scan_stop(device); if (device->scan_pending) dbus_pending_reply(&device->scan_pending, @@ -2156,7 +2124,6 @@ struct device *device_create(struct wiphy *wiphy, struct netdev *netdev) const uint8_t action_ap_roam_prefix[2] = { 0x0a, 0x07 }; device = l_new(struct device, 1); - watchlist_init(&device->state_watches, NULL); device->index = ifindex; device->wiphy = wiphy; device->netdev = netdev; @@ -2182,10 +2149,12 @@ struct device *device_create(struct wiphy *wiphy, struct netdev *netdev) action_ap_roam_prefix, sizeof(action_ap_roam_prefix), device_ap_roam_frame_event, device); - if (netdev_get_is_up(netdev) && + device->powered = netdev_get_is_up(netdev); + + if (device->powered && netdev_get_iftype(netdev) == NETDEV_IFTYPE_STATION) { device->station = station_create(device->wiphy, device->netdev); - device_enter_state(device, DEVICE_STATE_AUTOCONNECT); + device_enter_state(device, STATION_STATE_AUTOCONNECT); } return device; @@ -2213,8 +2182,6 @@ static void device_free(void *user) } - watchlist_destroy(&device->state_watches); - dbus = dbus_get_bus(); l_dbus_unregister_object(dbus, device_get_path(device)); diff --git a/src/device.h b/src/device.h index d3c8de47..7ac0c296 100644 --- a/src/device.h +++ b/src/device.h @@ -28,30 +28,10 @@ struct wiphy; struct netdev; struct device; -enum device_state { - DEVICE_STATE_OFF = 0, /* Interface down */ - DEVICE_STATE_DISCONNECTED, /* Disconnected, no auto-connect */ - DEVICE_STATE_AUTOCONNECT, /* Disconnected, try auto-connect */ - DEVICE_STATE_CONNECTING, /* Connecting */ - DEVICE_STATE_CONNECTED, - DEVICE_STATE_DISCONNECTING, - DEVICE_STATE_ROAMING -}; - -typedef void (*device_state_watch_func_t)(enum device_state, void *userdata); -typedef void (*device_destroy_func_t)(void *userdata); - struct network *device_get_connected_network(struct device *device); const char *device_get_path(struct device *device); bool device_is_busy(struct device *device); struct wiphy *device_get_wiphy(struct device *device); -enum device_state device_get_state(struct device *device); - -uint32_t device_add_state_watch(struct device *device, - device_state_watch_func_t func, - void *user_data, - device_destroy_func_t destroy); -bool device_remove_state_watch(struct device *device, uint32_t id); void device_set_scan_results(struct device *device, struct l_queue *bss_list, bool add_to_autoconnect); diff --git a/src/station.c b/src/station.c index d91318d2..517e0f8c 100644 --- a/src/station.c +++ b/src/station.c @@ -32,6 +32,7 @@ #include "src/util.h" #include "src/iwd.h" #include "src/common.h" +#include "src/watchlist.h" #include "src/scan.h" #include "src/netdev.h" #include "src/wiphy.h" @@ -496,6 +497,52 @@ not_supported: return NULL; } +const char *station_state_to_string(enum station_state state) +{ + switch (state) { + case STATION_STATE_DISCONNECTED: + return "disconnected"; + case STATION_STATE_AUTOCONNECT: + return "autoconnect"; + case STATION_STATE_CONNECTING: + return "connecting"; + case STATION_STATE_CONNECTED: + return "connected"; + case STATION_STATE_DISCONNECTING: + return "disconnecting"; + case STATION_STATE_ROAMING: + return "roaming"; + } + + return "invalid"; +} + +void station_enter_state(struct station *station, enum station_state state) +{ + station->state = state; + + WATCHLIST_NOTIFY(&station->state_watches, + station_state_watch_func_t, state); +} + +enum station_state station_get_state(struct station *station) +{ + return station->state; +} + +uint32_t station_add_state_watch(struct station *station, + station_state_watch_func_t func, + void *user_data, + station_destroy_func_t destroy) +{ + return watchlist_add(&station->state_watches, func, user_data, destroy); +} + +bool station_remove_state_watch(struct station *station, uint32_t id) +{ + return watchlist_remove(&station->state_watches, id); +} + struct station *station_find(uint32_t ifindex) { const struct l_queue_entry *entry; @@ -516,6 +563,7 @@ struct station *station_create(struct wiphy *wiphy, struct netdev *netdev) struct station *station; station = l_new(struct station, 1); + watchlist_init(&station->state_watches, NULL); station->bss_list = l_queue_new(); station->networks = l_hashmap_new(); @@ -544,6 +592,8 @@ void station_free(struct station *station) l_queue_destroy(station->bss_list, bss_free); l_queue_destroy(station->autoconnect_list, l_free); + watchlist_destroy(&station->state_watches); + l_free(station); } diff --git a/src/station.h b/src/station.h index e27974b3..22cb86b3 100644 --- a/src/station.h +++ b/src/station.h @@ -28,7 +28,21 @@ enum security; struct scan_bss; struct network; +enum station_state { + STATION_STATE_DISCONNECTED, /* Disconnected, no auto-connect */ + STATION_STATE_AUTOCONNECT, /* Disconnected, try auto-connect */ + STATION_STATE_CONNECTING, /* Connecting */ + STATION_STATE_CONNECTED, + STATION_STATE_DISCONNECTING, + STATION_STATE_ROAMING +}; + +typedef void (*station_state_watch_func_t)(enum station_state, void *userdata); +typedef void (*station_destroy_func_t)(void *userdata); + struct station { + enum station_state state; + struct watchlist state_watches; struct scan_bss *connected_bss; struct network *connected_network; struct l_queue *autoconnect_list; @@ -60,6 +74,15 @@ struct handshake_state *station_handshake_setup(struct station *station, struct network *network, struct scan_bss *bss); +const char *station_state_to_string(enum station_state state); +void station_enter_state(struct station *station, enum station_state state); +enum station_state station_get_state(struct station *station); +uint32_t station_add_state_watch(struct station *station, + station_state_watch_func_t func, + void *user_data, + station_destroy_func_t destroy); +bool station_remove_state_watch(struct station *station, uint32_t id); + struct station *station_find(uint32_t ifindex); struct station *station_create(struct wiphy *wiphy, struct netdev *netdev); void station_free(struct station *station); diff --git a/src/wsc.c b/src/wsc.c index c70aa22c..7efe5f7e 100644 --- a/src/wsc.c +++ b/src/wsc.c @@ -30,8 +30,10 @@ #include "src/dbus.h" #include "src/netdev.h" +#include "src/watchlist.h" #include "src/device.h" #include "src/wiphy.h" +#include "src/station.h" #include "src/scan.h" #include "src/ie.h" #include "src/wscutil.h" @@ -50,7 +52,7 @@ static uint32_t netdev_watch = 0; struct wsc { struct netdev *netdev; - struct device *device; /* TODO: Should be Station */ + struct station *station; struct l_dbus_message *pending; struct l_dbus_message *pending_cancel; uint8_t *wsc_ies; @@ -58,7 +60,7 @@ struct wsc { struct l_timeout *walk_timer; uint32_t scan_id; struct scan_bss *target; - uint32_t device_state_watch; + uint32_t station_state_watch; struct { char ssid[33]; enum security security; @@ -112,12 +114,13 @@ static struct l_dbus_message *wsc_error_time_expired(struct l_dbus_message *msg) } static void wsc_try_credentials(struct wsc *wsc) { + struct device *device = netdev_get_device(wsc->netdev); unsigned int i; struct network *network; struct scan_bss *bss; for (i = 0; i < wsc->n_creds; i++) { - network = device_network_find(wsc->device, + network = device_network_find(device, wsc->creds[i].ssid, wsc->creds[i].security); if (!network) @@ -135,7 +138,7 @@ static void wsc_try_credentials(struct wsc *wsc) !network_set_psk(network, wsc->creds[i].psk)) continue; - device_connect_network(wsc->device, network, bss, wsc->pending); + device_connect_network(device, network, bss, wsc->pending); l_dbus_message_unref(wsc->pending); wsc->pending = NULL; @@ -144,7 +147,7 @@ static void wsc_try_credentials(struct wsc *wsc) dbus_pending_reply(&wsc->pending, wsc_error_not_reachable(wsc->pending)); - device_set_autoconnect(wsc->device, true); + device_set_autoconnect(device, true); done: memset(wsc->creds, 0, sizeof(wsc->creds)); wsc->n_creds = 0; @@ -189,6 +192,7 @@ static void wsc_disconnect_cb(struct netdev *netdev, bool success, void *user_data) { struct wsc *wsc = user_data; + struct device *device = netdev_get_device(wsc->netdev); struct l_dbus_message *reply; l_debug("%p, success: %d", wsc, success); @@ -199,13 +203,14 @@ static void wsc_disconnect_cb(struct netdev *netdev, bool success, l_dbus_message_set_arguments(reply, ""); dbus_pending_reply(&wsc->pending_cancel, reply); - device_set_autoconnect(wsc->device, true); + device_set_autoconnect(device, true); } static void wsc_connect_cb(struct netdev *netdev, enum netdev_result result, void *user_data) { struct wsc *wsc = user_data; + struct device *device = netdev_get_device(wsc->netdev); l_debug("%d, result: %d", netdev_get_ifindex(wsc->netdev), result); @@ -235,7 +240,7 @@ static void wsc_connect_cb(struct netdev *netdev, enum netdev_result result, break; } - device_set_autoconnect(wsc->device, true); + device_set_autoconnect(device, true); } static void wsc_credential_obtained(struct wsc *wsc, @@ -469,23 +474,24 @@ static void wsc_connect(struct wsc *wsc) wsc->wsc_association = true; } -static void device_state_watch(enum device_state state, void *userdata) +static void station_state_watch(enum station_state state, void *userdata) { struct wsc *wsc = userdata; - if (state != DEVICE_STATE_DISCONNECTED) + if (state != STATION_STATE_DISCONNECTED) return; l_debug("%p", wsc); - device_remove_state_watch(wsc->device, wsc->device_state_watch); - wsc->device_state_watch = 0; + station_remove_state_watch(wsc->station, wsc->station_state_watch); + wsc->station_state_watch = 0; wsc_connect(wsc); } static void wsc_check_can_connect(struct wsc *wsc, struct scan_bss *target) { + struct device *device = netdev_get_device(wsc->netdev); l_debug("%p", wsc); /* @@ -493,27 +499,27 @@ static void wsc_check_can_connect(struct wsc *wsc, struct scan_bss *target) * be triggering any more scans while disconnecting / connecting */ wsc->target = target; - device_set_autoconnect(wsc->device, false); + device_set_autoconnect(device, false); - switch (device_get_state(wsc->device)) { - case DEVICE_STATE_DISCONNECTED: + switch (station_get_state(wsc->station)) { + case STATION_STATE_DISCONNECTED: wsc_connect(wsc); return; - case DEVICE_STATE_CONNECTING: - case DEVICE_STATE_CONNECTED: - if (device_disconnect(wsc->device) < 0) + case STATION_STATE_CONNECTING: + case STATION_STATE_CONNECTED: + if (device_disconnect(device) < 0) goto error; /* fall through */ - case DEVICE_STATE_DISCONNECTING: - wsc->device_state_watch = - device_add_state_watch(wsc->device, device_state_watch, - wsc, NULL); + case STATION_STATE_DISCONNECTING: + wsc->station_state_watch = + station_add_state_watch(wsc->station, + station_state_watch, + wsc, NULL); return; - case DEVICE_STATE_AUTOCONNECT: - case DEVICE_STATE_OFF: - case DEVICE_STATE_ROAMING: - l_warn("wsc_check_can_connect: invalid device state"); + case STATION_STATE_AUTOCONNECT: + case STATION_STATE_ROAMING: + l_warn("wsc_check_can_connect: invalid station state"); break; } error: @@ -564,6 +570,7 @@ static bool push_button_scan_results(uint32_t wiphy_id, uint32_t ifindex, void *userdata) { struct wsc *wsc = userdata; + struct device *device = netdev_get_device(wsc->netdev); struct scan_bss *bss_2g; struct scan_bss *bss_5g; struct scan_bss *target; @@ -666,7 +673,7 @@ static bool push_button_scan_results(uint32_t wiphy_id, uint32_t ifindex, } wsc_cancel_scan(wsc); - device_set_scan_results(wsc->device, bss_list, false); + device_set_scan_results(device, bss_list, false); l_debug("Found AP to connect to: %s", util_address_to_string(target->addr)); @@ -723,6 +730,7 @@ static bool pin_scan_results(uint32_t wiphy_id, uint32_t ifindex, int err, static const uint8_t wildcard_address[] = { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff }; struct wsc *wsc = userdata; + struct device *device = netdev_get_device(wsc->netdev); struct scan_bss *target = NULL; const struct l_queue_entry *bss_entry; struct wsc_probe_response probe_response; @@ -813,7 +821,7 @@ static bool pin_scan_results(uint32_t wiphy_id, uint32_t ifindex, int err, } wsc_cancel_scan(wsc); - device_set_scan_results(wsc->device, bss_list, false); + device_set_scan_results(device, bss_list, false); l_debug("Found AP to connect to: %s", util_address_to_string(target->addr)); @@ -897,6 +905,10 @@ static struct l_dbus_message *wsc_push_button(struct l_dbus *dbus, if (wsc->pending) return dbus_error_busy(message); + wsc->station = station_find(netdev_get_ifindex(wsc->netdev)); + if (!wsc->station) + return dbus_error_not_available(message); + if (!wsc_initiate_scan(wsc, WSC_DEVICE_PASSWORD_ID_PUSH_BUTTON, push_button_scan_results)) return dbus_error_failed(message); @@ -942,6 +954,10 @@ static struct l_dbus_message *wsc_start_pin(struct l_dbus *dbus, if (wsc->pending) return dbus_error_busy(message); + wsc->station = station_find(netdev_get_ifindex(wsc->netdev)); + if (!wsc->station) + return dbus_error_not_available(message); + if (!l_dbus_message_get_arguments(message, "s", &pin)) return dbus_error_invalid_args(message); @@ -976,9 +992,10 @@ static struct l_dbus_message *wsc_cancel(struct l_dbus *dbus, wsc_cancel_scan(wsc); - if (wsc->device_state_watch) { - device_remove_state_watch(wsc->device, wsc->device_state_watch); - wsc->device_state_watch = 0; + if (wsc->station_state_watch) { + station_remove_state_watch(wsc->station, + wsc->station_state_watch); + wsc->station_state_watch = 0; wsc->target = NULL; } @@ -1021,9 +1038,10 @@ static void wsc_free(void *userdata) wsc_cancel_scan(wsc); - if (wsc->device_state_watch) { - device_remove_state_watch(wsc->device, wsc->device_state_watch); - wsc->device_state_watch = 0; + if (wsc->station_state_watch) { + station_remove_state_watch(wsc->station, + wsc->station_state_watch); + wsc->station_state_watch = 0; wsc->target = NULL; } @@ -1048,7 +1066,6 @@ static void wsc_add_interface(struct netdev *netdev) wsc = l_new(struct wsc, 1); wsc->netdev = netdev; - wsc->device = netdev_get_device(netdev); if (!l_dbus_object_add_interface(dbus, netdev_get_path(netdev), IWD_WSC_INTERFACE,