summaryrefslogtreecommitdiff
path: root/src/provider.c
diff options
context:
space:
mode:
authorJukka Rissanen <jukka.rissanen@linux.intel.com>2012-04-03 14:07:24 +0300
committerPatrik Flykt <patrik.flykt@linux.intel.com>2012-04-12 11:00:42 +0300
commit709aaebeaca495292306f95d3fb1bc346f331d67 (patch)
tree476e790b61bf7b7fae4645828029abadcf38d3ff /src/provider.c
parent4ca9544819ca979354dabdf24f4f4f42c2a416d5 (diff)
downloadconnman-709aaebeaca495292306f95d3fb1bc346f331d67.tar.gz
connman-709aaebeaca495292306f95d3fb1bc346f331d67.tar.bz2
connman-709aaebeaca495292306f95d3fb1bc346f331d67.zip
provider: Disconnect VPN when phy service is disconnected
If the VPN is connected and the underlaying service is disconnected, then we must also disconnect the VPN if it is still connected.
Diffstat (limited to 'src/provider.c')
-rw-r--r--src/provider.c62
1 files changed, 62 insertions, 0 deletions
diff --git a/src/provider.c b/src/provider.c
index 42fd112f..00f3f4c5 100644
--- a/src/provider.c
+++ b/src/provider.c
@@ -1281,9 +1281,71 @@ static void provider_offline_mode(connman_bool_t enabled)
}
+static struct connman_provider *provider_get(int index)
+{
+ GHashTableIter iter;
+ gpointer value, key;
+
+ g_hash_table_iter_init(&iter, provider_hash);
+
+ while (g_hash_table_iter_next(&iter, &key, &value) == TRUE) {
+ struct connman_provider *provider = value;
+
+ if (provider->index == index)
+ return provider;
+ }
+
+ return NULL;
+}
+
+static void provider_service_changed(struct connman_service *service,
+ enum connman_service_state state)
+{
+ struct connman_provider *provider;
+ int vpn_index, service_index;
+
+ if (service == NULL)
+ return;
+
+ switch (state) {
+ case CONNMAN_SERVICE_STATE_UNKNOWN:
+ case CONNMAN_SERVICE_STATE_IDLE:
+ case CONNMAN_SERVICE_STATE_ASSOCIATION:
+ case CONNMAN_SERVICE_STATE_CONFIGURATION:
+ case CONNMAN_SERVICE_STATE_READY:
+ case CONNMAN_SERVICE_STATE_ONLINE:
+ return;
+ case CONNMAN_SERVICE_STATE_DISCONNECT:
+ case CONNMAN_SERVICE_STATE_FAILURE:
+ break;
+ }
+
+ service_index = __connman_service_get_index(service);
+
+ vpn_index = __connman_connection_get_vpn_index(service_index);
+
+ DBG("service %p %s state %d index %d/%d", service,
+ __connman_service_get_ident(service),
+ state, service_index, vpn_index);
+
+ if (vpn_index < 0)
+ return;
+
+ provider = provider_get(vpn_index);
+ if (provider == NULL)
+ return;
+
+ DBG("disconnect %p index %d", provider, vpn_index);
+
+ __connman_provider_disconnect(provider);
+
+ return;
+}
+
static struct connman_notifier provider_notifier = {
.name = "provider",
.offline_mode = provider_offline_mode,
+ .service_state_changed = provider_service_changed,
};
int __connman_provider_init(void)