diff options
author | Marcel Holtmann <marcel@holtmann.org> | 2009-11-24 00:26:09 +0100 |
---|---|---|
committer | Marcel Holtmann <marcel@holtmann.org> | 2009-11-24 00:26:09 +0100 |
commit | 5253d820574337a5675e3c9cfd72eac5b6b5d1ba (patch) | |
tree | a3556fbd4f61e213bcc981377423c33756fea9f3 /src | |
parent | 040d660d41cf83cb068e45e63646c94b8f17251f (diff) | |
download | ofono-5253d820574337a5675e3c9cfd72eac5b6b5d1ba.tar.bz2 |
Add support bringing GPRS interfaces up and down as needed
Diffstat (limited to 'src')
-rw-r--r-- | src/gprs.c | 50 |
1 files changed, 50 insertions, 0 deletions
@@ -26,6 +26,10 @@ #include <string.h> #include <stdio.h> #include <errno.h> +#include <unistd.h> +#include <sys/ioctl.h> +#include <sys/socket.h> +#include <net/if.h> #include <glib.h> #include <gdbus.h> @@ -269,15 +273,59 @@ static void pri_context_signal_settings(struct pri_context *ctx) g_dbus_send_message(conn, signal); } +static void pri_ifupdown(const char *interface, ofono_bool_t active) +{ + struct ifreq ifr; + int sk; + + if (!interface) + return; + + sk = socket(PF_INET, SOCK_DGRAM, 0); + if (sk < 0) + return; + + memset(&ifr, 0, sizeof(ifr)); + strncpy(ifr.ifr_name, interface, IFNAMSIZ); + + if (ioctl(sk, SIOCGIFFLAGS, &ifr) < 0) + goto done; + + if (active == TRUE) { + if (ifr.ifr_flags & IFF_UP) + goto done; + ifr.ifr_flags |= IFF_UP; + } else { + if (!(ifr.ifr_flags & IFF_UP)) + goto done; + ifr.ifr_flags &= ~IFF_UP; + } + + if (ioctl(sk, SIOCSIFFLAGS, &ifr) < 0) + ofono_error("Failed to change interface flags"); + +done: + close(sk); +} + static void pri_reset_context_settings(struct pri_context *ctx) { + char *interface; + if (ctx->settings == NULL) return; + interface = ctx->settings->interface; + ctx->settings->interface = NULL; + context_settings_free(ctx->settings); ctx->settings = NULL; pri_context_signal_settings(ctx); + + pri_ifupdown(interface, FALSE); + + g_free(interface); } static void pri_update_context_settings(struct pri_context *ctx, @@ -298,6 +346,8 @@ static void pri_update_context_settings(struct pri_context *ctx, ctx->settings->gateway = g_strdup(gateway); ctx->settings->dns = g_strdupv((char **)dns); + pri_ifupdown(interface, TRUE); + pri_context_signal_settings(ctx); } |