mirror of
https://git.kernel.org/pub/scm/network/wireless/iwd.git
synced 2024-12-22 13:02:44 +01:00
station: Split autoconnect state into two sub states
The auto-connect state will now consist of the two phases: STATION_STATE_AUTOCONNECT_QUICK and STATION_STATE_AUTOCONNECT_FULL. The auto-connect will always start with STATION_STATE_AUTOCONNECT_QUICK and then transition into STATION_STATE_AUTOCONNECT_FULL if no connection has been established. During STATION_STATE_AUTOCONNECT_QUICK phase we take advantage of the wireless scans with the limited number of channels on which the known networks have been observed before. This approach allows to shorten the time required for the network sweeps, therefore decreases the connection latency if the connection is possible. Thereafter, if no connection has been established after the first phase we transition into STATION_STATE_AUTOCONNECT_FULL and do the periodic scan just like we did before the split in STATION_STATE_AUTOCONNECT state.
This commit is contained in:
parent
405785cd0b
commit
734c9ad2f6
@ -105,12 +105,19 @@ struct network *station_get_connected_network(struct station *station)
|
|||||||
bool station_is_busy(struct station *station)
|
bool station_is_busy(struct station *station)
|
||||||
{
|
{
|
||||||
if (station->state != STATION_STATE_DISCONNECTED &&
|
if (station->state != STATION_STATE_DISCONNECTED &&
|
||||||
station->state != STATION_STATE_AUTOCONNECT)
|
station->state != STATION_STATE_AUTOCONNECT_FULL &&
|
||||||
|
station->state != STATION_STATE_AUTOCONNECT_QUICK)
|
||||||
return true;
|
return true;
|
||||||
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static bool station_is_autoconnecting(struct station *station)
|
||||||
|
{
|
||||||
|
return station->state == STATION_STATE_AUTOCONNECT_FULL ||
|
||||||
|
station->state == STATION_STATE_AUTOCONNECT_QUICK;
|
||||||
|
}
|
||||||
|
|
||||||
struct autoconnect_entry {
|
struct autoconnect_entry {
|
||||||
uint16_t rank;
|
uint16_t rank;
|
||||||
struct network *network;
|
struct network *network;
|
||||||
@ -615,7 +622,7 @@ static bool new_scan_results(int err, struct l_queue *bss_list, void *userdata)
|
|||||||
if (err)
|
if (err)
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
autoconnect = station_get_state(station) == STATION_STATE_AUTOCONNECT;
|
autoconnect = station_is_autoconnecting(station);
|
||||||
station_set_scan_results(station, bss_list, autoconnect);
|
station_set_scan_results(station, bss_list, autoconnect);
|
||||||
|
|
||||||
if (autoconnect)
|
if (autoconnect)
|
||||||
@ -679,8 +686,10 @@ static const char *station_state_to_string(enum station_state state)
|
|||||||
switch (state) {
|
switch (state) {
|
||||||
case STATION_STATE_DISCONNECTED:
|
case STATION_STATE_DISCONNECTED:
|
||||||
return "disconnected";
|
return "disconnected";
|
||||||
case STATION_STATE_AUTOCONNECT:
|
case STATION_STATE_AUTOCONNECT_QUICK:
|
||||||
return "autoconnect";
|
return "autoconnect_quick";
|
||||||
|
case STATION_STATE_AUTOCONNECT_FULL:
|
||||||
|
return "autoconnect_full";
|
||||||
case STATION_STATE_CONNECTING:
|
case STATION_STATE_CONNECTING:
|
||||||
return "connecting";
|
return "connecting";
|
||||||
case STATION_STATE_CONNECTED:
|
case STATION_STATE_CONNECTED:
|
||||||
@ -705,15 +714,16 @@ static void station_enter_state(struct station *station,
|
|||||||
station_state_to_string(station->state),
|
station_state_to_string(station->state),
|
||||||
station_state_to_string(state));
|
station_state_to_string(state));
|
||||||
|
|
||||||
disconnected = station->state <= STATION_STATE_AUTOCONNECT;
|
disconnected = !station_is_busy(station);
|
||||||
|
|
||||||
if ((disconnected && state > STATION_STATE_AUTOCONNECT) ||
|
if ((disconnected && state > STATION_STATE_AUTOCONNECT_FULL) ||
|
||||||
(!disconnected && state != station->state))
|
(!disconnected && state != station->state))
|
||||||
l_dbus_property_changed(dbus, netdev_get_path(station->netdev),
|
l_dbus_property_changed(dbus, netdev_get_path(station->netdev),
|
||||||
IWD_STATION_INTERFACE, "State");
|
IWD_STATION_INTERFACE, "State");
|
||||||
|
|
||||||
switch (state) {
|
switch (state) {
|
||||||
case STATION_STATE_AUTOCONNECT:
|
case STATION_STATE_AUTOCONNECT_QUICK:
|
||||||
|
case STATION_STATE_AUTOCONNECT_FULL:
|
||||||
scan_periodic_start(index, periodic_scan_trigger,
|
scan_periodic_start(index, periodic_scan_trigger,
|
||||||
new_scan_results, station);
|
new_scan_results, station);
|
||||||
break;
|
break;
|
||||||
@ -765,9 +775,9 @@ bool station_set_autoconnect(struct station *station, bool autoconnect)
|
|||||||
station->autoconnect = autoconnect;
|
station->autoconnect = autoconnect;
|
||||||
|
|
||||||
if (station->state == STATION_STATE_DISCONNECTED && autoconnect)
|
if (station->state == STATION_STATE_DISCONNECTED && autoconnect)
|
||||||
station_enter_state(station, STATION_STATE_AUTOCONNECT);
|
station_enter_state(station, STATION_STATE_AUTOCONNECT_QUICK);
|
||||||
|
|
||||||
if (station->state == STATION_STATE_AUTOCONNECT && !autoconnect)
|
if (station_is_autoconnecting(station) && !autoconnect)
|
||||||
station_enter_state(station, STATION_STATE_DISCONNECTED);
|
station_enter_state(station, STATION_STATE_DISCONNECTED);
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
@ -819,7 +829,7 @@ static void station_disassociated(struct station *station)
|
|||||||
station_enter_state(station, STATION_STATE_DISCONNECTED);
|
station_enter_state(station, STATION_STATE_DISCONNECTED);
|
||||||
|
|
||||||
if (station->autoconnect)
|
if (station->autoconnect)
|
||||||
station_enter_state(station, STATION_STATE_AUTOCONNECT);
|
station_enter_state(station, STATION_STATE_AUTOCONNECT_QUICK);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void station_connect_cb(struct netdev *netdev, enum netdev_result result,
|
static void station_connect_cb(struct netdev *netdev, enum netdev_result result,
|
||||||
@ -2002,7 +2012,7 @@ static void station_disconnect_cb(struct netdev *netdev, bool success,
|
|||||||
station_enter_state(station, STATION_STATE_DISCONNECTED);
|
station_enter_state(station, STATION_STATE_DISCONNECTED);
|
||||||
|
|
||||||
if (station->autoconnect)
|
if (station->autoconnect)
|
||||||
station_enter_state(station, STATION_STATE_AUTOCONNECT);
|
station_enter_state(station, STATION_STATE_AUTOCONNECT_QUICK);
|
||||||
}
|
}
|
||||||
|
|
||||||
int station_disconnect(struct station *station)
|
int station_disconnect(struct station *station)
|
||||||
@ -2044,8 +2054,7 @@ static struct l_dbus_message *station_dbus_disconnect(struct l_dbus *dbus,
|
|||||||
*/
|
*/
|
||||||
station_set_autoconnect(station, false);
|
station_set_autoconnect(station, false);
|
||||||
|
|
||||||
if (station->state == STATION_STATE_AUTOCONNECT ||
|
if (!station_is_busy(station))
|
||||||
station->state == STATION_STATE_DISCONNECTED)
|
|
||||||
return l_dbus_message_new_method_return(message);
|
return l_dbus_message_new_method_return(message);
|
||||||
|
|
||||||
result = station_disconnect(station);
|
result = station_disconnect(station);
|
||||||
@ -2389,11 +2398,13 @@ static bool station_property_get_state(struct l_dbus *dbus,
|
|||||||
void *user_data)
|
void *user_data)
|
||||||
{
|
{
|
||||||
struct station *station = user_data;
|
struct station *station = user_data;
|
||||||
const char *statestr = station_state_to_string(station->state);
|
const char *statestr;
|
||||||
|
|
||||||
/* Special case. For now we treat AUTOCONNECT as disconnected */
|
if (!station_is_busy(station))
|
||||||
if (station->state == STATION_STATE_AUTOCONNECT)
|
/* Special case. For now we treat AUTOCONNECT as disconnected */
|
||||||
statestr = "disconnected";
|
statestr = "disconnected";
|
||||||
|
else
|
||||||
|
statestr = station_state_to_string(station->state);
|
||||||
|
|
||||||
l_dbus_message_builder_append_basic(builder, 's', statestr);
|
l_dbus_message_builder_append_basic(builder, 's', statestr);
|
||||||
return true;
|
return true;
|
||||||
|
@ -30,9 +30,14 @@ struct scan_bss;
|
|||||||
struct network;
|
struct network;
|
||||||
|
|
||||||
enum station_state {
|
enum station_state {
|
||||||
STATION_STATE_DISCONNECTED, /* Disconnected, no auto-connect */
|
/* Disconnected, no auto-connect */
|
||||||
STATION_STATE_AUTOCONNECT, /* Disconnected, try auto-connect */
|
STATION_STATE_DISCONNECTED,
|
||||||
STATION_STATE_CONNECTING, /* Connecting */
|
/* Disconnected, try auto-connect with quick scan */
|
||||||
|
STATION_STATE_AUTOCONNECT_QUICK,
|
||||||
|
/* Disconnected, try auto-connect with full scan */
|
||||||
|
STATION_STATE_AUTOCONNECT_FULL,
|
||||||
|
/* Connecting */
|
||||||
|
STATION_STATE_CONNECTING,
|
||||||
STATION_STATE_CONNECTED,
|
STATION_STATE_CONNECTED,
|
||||||
STATION_STATE_DISCONNECTING,
|
STATION_STATE_DISCONNECTING,
|
||||||
STATION_STATE_ROAMING
|
STATION_STATE_ROAMING
|
||||||
|
@ -517,7 +517,8 @@ static void wsc_check_can_connect(struct wsc *wsc, struct scan_bss *target)
|
|||||||
station_state_watch,
|
station_state_watch,
|
||||||
wsc, NULL);
|
wsc, NULL);
|
||||||
return;
|
return;
|
||||||
case STATION_STATE_AUTOCONNECT:
|
case STATION_STATE_AUTOCONNECT_QUICK:
|
||||||
|
case STATION_STATE_AUTOCONNECT_FULL:
|
||||||
case STATION_STATE_ROAMING:
|
case STATION_STATE_ROAMING:
|
||||||
l_warn("wsc_check_can_connect: invalid station state");
|
l_warn("wsc_check_can_connect: invalid station state");
|
||||||
break;
|
break;
|
||||||
|
Loading…
Reference in New Issue
Block a user