station: Disconnect, if needed, on a new connection attempt

Previously, iwd used to throw net.connman.iwd.Busy when connection
attempt was made while connected. The new behavior allows iwd to
seamlessly disconnect from the connected network and attempt a new
connection.
This commit is contained in:
Tim Kourt 2019-07-23 18:12:57 -07:00 committed by Denis Kenzior
parent 60078478cf
commit d0ee923dda
2 changed files with 52 additions and 5 deletions

View File

@ -1176,9 +1176,6 @@ static struct l_dbus_message *network_connect(struct l_dbus *dbus,
l_debug("");
if (station_is_busy(station))
return dbus_error_busy(message);
/*
* Select the best BSS to use at this time. If we have to query the
* agent this may not be the final choice because BSS visibility can

View File

@ -63,6 +63,8 @@ struct station {
struct watchlist state_watches;
struct scan_bss *connected_bss;
struct network *connected_network;
struct scan_bss *connect_pending_bss;
struct network *connect_pending_network;
struct l_queue *autoconnect_list;
struct l_queue *bss_list;
struct l_queue *hidden_bss_list_sorted;
@ -2225,6 +2227,53 @@ int __station_connect_network(struct station *station, struct network *network,
return 0;
}
static void station_disconnect_onconnect_cb(struct netdev *netdev, bool success,
void *user_data)
{
struct station *station = user_data;
int err;
station_enter_state(station, STATION_STATE_DISCONNECTED);
err = __station_connect_network(station,
station->connect_pending_network,
station->connect_pending_bss);
station->connect_pending_network = NULL;
station->connect_pending_bss = NULL;
if (err < 0) {
l_dbus_send(dbus_get_bus(),
dbus_error_from_errno(err,
station->connect_pending));
return;
}
station_enter_state(station, STATION_STATE_CONNECTING);
}
static void station_disconnect_onconnect(struct station *station,
struct network *network,
struct scan_bss *bss,
struct l_dbus_message *message)
{
if (netdev_disconnect(station->netdev, station_disconnect_onconnect_cb,
station) < 0) {
l_dbus_send(dbus_get_bus(),
dbus_error_from_errno(-EIO, message));
return;
}
station_reset_connection_state(station);
station_enter_state(station, STATION_STATE_DISCONNECTING);
station->connect_pending_network = network;
station->connect_pending_bss = bss;
station->connect_pending = l_dbus_message_ref(message);
}
void station_connect_network(struct station *station, struct network *network,
struct scan_bss *bss,
struct l_dbus_message *message)
@ -2233,8 +2282,9 @@ void station_connect_network(struct station *station, struct network *network,
int err;
if (station_is_busy(station)) {
err = -EBUSY;
goto error;
station_disconnect_onconnect(station, network, bss, message);
return;
}
err = __station_connect_network(station, network, bss);