wiphy: Add netdev state machine

This commit is contained in:
Denis Kenzior 2015-06-22 17:02:52 -05:00
parent cd1ef5acf7
commit a2be179f57
1 changed files with 67 additions and 2 deletions

View File

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