station: move the remaining scanning code from device

This commit is contained in:
Denis Kenzior 2018-09-04 17:32:18 -05:00
parent 58c8243114
commit b49ec9461b
3 changed files with 152 additions and 154 deletions

View File

@ -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(&params, 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, &params,
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));

View File

@ -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(&params, 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, &params,
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);

View File

@ -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);