mirror of
https://git.kernel.org/pub/scm/network/wireless/iwd.git
synced 2024-12-28 03:42:34 +01:00
station: move the remaining scanning code from device
This commit is contained in:
parent
58c8243114
commit
b49ec9461b
148
src/device.c
148
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));
|
||||
|
145
src/station.c
145
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);
|
||||
|
@ -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);
|
||||
|
Loading…
Reference in New Issue
Block a user