diff options
author | Jukka Rissanen <jukka.rissanen@linux.intel.com> | 2012-04-03 14:07:24 +0300 |
---|---|---|
committer | Patrik Flykt <patrik.flykt@linux.intel.com> | 2012-04-12 11:00:42 +0300 |
commit | 709aaebeaca495292306f95d3fb1bc346f331d67 (patch) | |
tree | 476e790b61bf7b7fae4645828029abadcf38d3ff /src/provider.c | |
parent | 4ca9544819ca979354dabdf24f4f4f42c2a416d5 (diff) | |
download | connman-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.c | 62 |
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) |