mirror of
https://git.kernel.org/pub/scm/network/wireless/iwd.git
synced 2024-11-16 17:09:24 +01:00
wiphy: Add netdev state machine
This commit is contained in:
parent
cd1ef5acf7
commit
a2be179f57
69
src/wiphy.c
69
src/wiphy.c
@ -64,11 +64,20 @@ struct network {
|
||||
bool ask_psk:1; /* Whether we should force-ask agent for PSK */
|
||||
};
|
||||
|
||||
enum netdev_state {
|
||||
NETDEV_STATE_DISCONNECTED = 0, /* Disconnected, no auto-connect */
|
||||
NETDEV_STATE_AUTOCONNECT, /* Disconnected, try auto-connect */
|
||||
NETDEV_STATE_CONNECTING, /* Connecting */
|
||||
NETDEV_STATE_CONNECTED,
|
||||
NETDEV_STATE_DISCONNECTING,
|
||||
};
|
||||
|
||||
struct netdev {
|
||||
uint32_t index;
|
||||
char name[IFNAMSIZ];
|
||||
uint32_t type;
|
||||
uint8_t addr[ETH_ALEN];
|
||||
enum netdev_state state;
|
||||
struct l_queue *bss_list;
|
||||
struct l_queue *old_bss_list;
|
||||
struct l_dbus_message *scan_pending;
|
||||
@ -196,6 +205,49 @@ static struct l_dbus_message *network_get_properties(struct l_dbus *dbus,
|
||||
return reply;
|
||||
}
|
||||
|
||||
static const char *netdev_state_to_string(enum netdev_state state)
|
||||
{
|
||||
switch (state) {
|
||||
case NETDEV_STATE_DISCONNECTED:
|
||||
return "disconnected";
|
||||
case NETDEV_STATE_AUTOCONNECT:
|
||||
return "autoconnect";
|
||||
case NETDEV_STATE_CONNECTING:
|
||||
return "connecting";
|
||||
case NETDEV_STATE_CONNECTED:
|
||||
return "connected";
|
||||
case NETDEV_STATE_DISCONNECTING:
|
||||
return "disconnecting";
|
||||
}
|
||||
|
||||
return "invalid";
|
||||
}
|
||||
|
||||
static void netdev_enter_state(struct netdev *netdev, enum netdev_state state)
|
||||
{
|
||||
l_debug("Old State: %s, new state: %s",
|
||||
netdev_state_to_string(netdev->state),
|
||||
netdev_state_to_string(state));
|
||||
|
||||
switch (state) {
|
||||
case NETDEV_STATE_AUTOCONNECT:
|
||||
scan_periodic_start(netdev->index);
|
||||
break;
|
||||
case NETDEV_STATE_DISCONNECTED:
|
||||
scan_periodic_stop(netdev->index);
|
||||
break;
|
||||
case NETDEV_STATE_CONNECTED:
|
||||
scan_periodic_stop(netdev->index);
|
||||
break;
|
||||
case NETDEV_STATE_CONNECTING:
|
||||
break;
|
||||
case NETDEV_STATE_DISCONNECTING:
|
||||
break;
|
||||
}
|
||||
|
||||
netdev->state = state;
|
||||
}
|
||||
|
||||
static void netdev_disassociated(struct netdev *netdev)
|
||||
{
|
||||
struct network *network = netdev->connected_network;
|
||||
@ -205,6 +257,8 @@ static void netdev_disassociated(struct netdev *netdev)
|
||||
|
||||
netdev->connected_bss = NULL;
|
||||
netdev->connected_network = NULL;
|
||||
|
||||
netdev_enter_state(netdev, NETDEV_STATE_AUTOCONNECT);
|
||||
}
|
||||
|
||||
static void netdev_lost_beacon(struct netdev *netdev)
|
||||
@ -297,6 +351,7 @@ static int mlme_authenticate_cmd(struct network *network, struct scan_bss *bss)
|
||||
|
||||
netdev->connected_bss = bss;
|
||||
netdev->connected_network = network;
|
||||
netdev_enter_state(netdev, NETDEV_STATE_CONNECTING);
|
||||
|
||||
return 0;
|
||||
}
|
||||
@ -419,7 +474,8 @@ static struct l_dbus_message *network_connect(struct l_dbus *dbus,
|
||||
|
||||
l_debug("");
|
||||
|
||||
if (netdev->connect_pending)
|
||||
if (netdev->state != NETDEV_STATE_DISCONNECTED &&
|
||||
netdev->state != NETDEV_STATE_AUTOCONNECT)
|
||||
return dbus_error_busy(message);
|
||||
|
||||
/*
|
||||
@ -756,7 +812,8 @@ static struct l_dbus_message *device_disconnect(struct l_dbus *dbus,
|
||||
|
||||
l_debug("");
|
||||
|
||||
if (netdev->connect_pending)
|
||||
if (netdev->state == NETDEV_STATE_CONNECTING ||
|
||||
netdev->state == NETDEV_STATE_DISCONNECTING)
|
||||
return dbus_error_busy(message);
|
||||
|
||||
if (!netdev->connected_bss)
|
||||
@ -773,6 +830,8 @@ static struct l_dbus_message *device_disconnect(struct l_dbus *dbus,
|
||||
netdev->connected_bss->addr);
|
||||
l_genl_family_send(nl80211, msg, genl_disconnect_cb, netdev, NULL);
|
||||
|
||||
netdev_enter_state(netdev, NETDEV_STATE_DISCONNECTING);
|
||||
|
||||
netdev->disconnect_pending = l_dbus_message_ref(message);
|
||||
|
||||
return NULL;
|
||||
@ -922,6 +981,7 @@ static void setting_keys_failed(struct netdev *netdev, uint16_t reason_code)
|
||||
msg_append_attr(msg, NL80211_ATTR_MAC, ETH_ALEN,
|
||||
netdev->connected_bss->addr);
|
||||
l_genl_family_send(nl80211, msg, deauthenticate_cb, netdev, NULL);
|
||||
netdev_enter_state(netdev, NETDEV_STATE_DISCONNECTING);
|
||||
}
|
||||
|
||||
static void handshake_failed(uint32_t ifindex,
|
||||
@ -938,6 +998,7 @@ static void handshake_failed(uint32_t ifindex,
|
||||
msg_append_attr(msg, NL80211_ATTR_REASON_CODE, 2, &reason_code);
|
||||
msg_append_attr(msg, NL80211_ATTR_MAC, ETH_ALEN, aa);
|
||||
l_genl_family_send(nl80211, msg, deauthenticate_cb, netdev, NULL);
|
||||
netdev_enter_state(netdev, NETDEV_STATE_DISCONNECTING);
|
||||
}
|
||||
|
||||
static void mlme_set_pairwise_key_cb(struct l_genl_msg *msg, void *data)
|
||||
@ -1097,6 +1158,8 @@ static void operstate_cb(bool result, void *user_data)
|
||||
l_dbus_message_set_arguments(reply, "");
|
||||
dbus_pending_reply(&netdev->connect_pending, reply);
|
||||
}
|
||||
|
||||
netdev_enter_state(netdev, NETDEV_STATE_CONNECTED);
|
||||
}
|
||||
|
||||
static void set_station_cb(struct l_genl_msg *msg, void *user_data)
|
||||
@ -1746,6 +1809,8 @@ static void interface_dump_callback(struct l_genl_msg *msg, void *user_data)
|
||||
|
||||
netdev_set_linkmode_and_operstate(netdev->index, 1,
|
||||
IF_OPER_DORMANT, NULL, NULL);
|
||||
|
||||
netdev_enter_state(netdev, NETDEV_STATE_AUTOCONNECT);
|
||||
}
|
||||
|
||||
l_debug("Found interface %s", netdev->name);
|
||||
|
Loading…
Reference in New Issue
Block a user