@@ -1487,6 +1487,23 @@ int __vpn_provider_disconnect(struct vpn_provider *provider)
return err;
}
+static bool is_connected_state(enum vpn_provider_state state)
+{
+ switch (state) {
+ case VPN_PROVIDER_STATE_UNKNOWN:
+ case VPN_PROVIDER_STATE_IDLE:
+ case VPN_PROVIDER_STATE_DISCONNECT:
+ case VPN_PROVIDER_STATE_FAILURE:
+ break;
+ case VPN_PROVIDER_STATE_CONNECT:
+ case VPN_PROVIDER_STATE_READY:
+ case VPN_PROVIDER_STATE_ASSOCIATION:
+ return true;
+ }
+
+ return false;
+}
+
static void connect_cb(struct vpn_provider *provider, void *user_data,
int error)
{
@@ -1509,6 +1526,8 @@ static void connect_cb(struct vpn_provider *provider, void *user_data,
* No reply, disconnect called by connmand because of
* connection timeout.
*/
+ vpn_provider_indicate_error(provider,
+ VPN_PROVIDER_ERROR_CONNECT_FAILED);
break;
case ENOMSG:
/* fall through */
@@ -1533,9 +1552,7 @@ static void connect_cb(struct vpn_provider *provider, void *user_data,
* process gets killed and vpn_died() is called to make
* the provider back to idle state.
*/
- if (provider->state == VPN_PROVIDER_STATE_CONNECT ||
- provider->state ==
- VPN_PROVIDER_STATE_READY) {
+ if (is_connected_state(provider->state)) {
if (provider->driver->set_state)
provider->driver->set_state(provider,
VPN_PROVIDER_STATE_DISCONNECT);
@@ -1597,6 +1614,17 @@ int __vpn_provider_connect(struct vpn_provider *provider, DBusMessage *msg)
if (reply)
g_dbus_send_message(connection, reply);
+ return -EINPROGRESS;
+ case VPN_PROVIDER_STATE_ASSOCIATION:
+ /*
+ * Do not interrupt user when inputting credentials via agent.
+ * The driver is in CONNECT state that would return EINPROGRESS
+ * and change provider state to CONNECT.
+ */
+ reply = __connman_error_in_progress(msg);
+ if (reply)
+ g_dbus_send_message(connection, reply);
+
return -EINPROGRESS;
case VPN_PROVIDER_STATE_UNKNOWN:
case VPN_PROVIDER_STATE_IDLE:
@@ -1626,7 +1654,7 @@ int __vpn_provider_connect(struct vpn_provider *provider, DBusMessage *msg)
return -EOPNOTSUPP;
if (err == -EINPROGRESS)
- vpn_provider_set_state(provider, VPN_PROVIDER_STATE_CONNECT);
+ vpn_provider_set_state(provider, VPN_PROVIDER_STATE_ASSOCIATION);
return err;
}
@@ -1767,6 +1795,8 @@ static const char *state2string(enum vpn_provider_state state)
break;
case VPN_PROVIDER_STATE_IDLE:
return "idle";
+ case VPN_PROVIDER_STATE_ASSOCIATION:
+ return "association";
case VPN_PROVIDER_STATE_CONNECT:
return "configuration";
case VPN_PROVIDER_STATE_READY:
@@ -1875,6 +1905,9 @@ static void append_state(DBusMessageIter *iter,
case VPN_PROVIDER_STATE_IDLE:
str = "idle";
break;
+ case VPN_PROVIDER_STATE_ASSOCIATION:
+ str = "association";
+ break;
case VPN_PROVIDER_STATE_CONNECT:
str = "configuration";
break;
@@ -2026,6 +2059,10 @@ int vpn_provider_set_state(struct vpn_provider *provider,
case VPN_PROVIDER_STATE_IDLE:
return set_connected(provider, false);
case VPN_PROVIDER_STATE_CONNECT:
+ if (provider->driver && provider->driver->set_state)
+ provider->driver->set_state(provider, state);
+ return provider_indicate_state(provider, state);
+ case VPN_PROVIDER_STATE_ASSOCIATION:
return provider_indicate_state(provider, state);
case VPN_PROVIDER_STATE_READY:
return set_connected(provider, true);
@@ -44,6 +44,12 @@ enum vpn_provider_state {
VPN_PROVIDER_STATE_READY = 3,
VPN_PROVIDER_STATE_DISCONNECT = 4,
VPN_PROVIDER_STATE_FAILURE = 5,
+ /*
+ * Special state to indicate that user interaction is being waited for
+ * and disconnect timeout in connmand should not terminate this VPN but
+ * to let the agent timeout handle the case.
+ */
+ VPN_PROVIDER_STATE_ASSOCIATION = 6,
};
enum vpn_provider_error {