From 9d7329da99437412f202a923ca5c62235e3ba9b4 Mon Sep 17 00:00:00 2001 From: Carsten Haitzler Date: Sun, 31 Aug 2008 01:51:27 +0000 Subject: [PATCH] some mixer fixes (icon, code), a connman module - beware. not fully working (well working up to the point whre you can select a network - at that point connman itself just stares dumbly at you and does nothing - so right now it's some form of connman bug i suspect). it doesnt save config or load - so you need to re-init each time and the graphcis are... let's just say.. sucky. for now theyare test graphics only. suto-connect if network found etc. doesnt work as well.. can't even connect first time... i can clean the rest up so in theory it works - but in practice, won't be useful until connmand (back end) works properly. SVN revision: 35755 --- config/.cvsignore | 3 + config/default/.cvsignore | 3 + configure.in | 2 + data/themes/Makefile.am | 3 +- data/themes/default.edc | 1 + data/themes/default_connman.edc | 412 +++++++ src/modules/Makefile.am | 3 +- src/modules/connman/.cvsignore | 9 + src/modules/connman/Makefile.am | 33 + src/modules/connman/e-module-connman.edj | Bin 0 -> 8255 bytes src/modules/connman/e_iface.c | 1348 +++++++++++++++++++++ src/modules/connman/e_iface.h | 116 ++ src/modules/connman/e_mod_main.c | 1409 ++++++++++++++++++++++ src/modules/connman/e_mod_main.h | 13 + src/modules/connman/module.desktop.in | 6 + src/modules/mixer/e_mod_main.c | 4 +- 16 files changed, 3361 insertions(+), 4 deletions(-) create mode 100644 config/.cvsignore create mode 100644 config/default/.cvsignore create mode 100644 data/themes/default_connman.edc create mode 100644 src/modules/connman/.cvsignore create mode 100644 src/modules/connman/Makefile.am create mode 100644 src/modules/connman/e-module-connman.edj create mode 100644 src/modules/connman/e_iface.c create mode 100644 src/modules/connman/e_iface.h create mode 100644 src/modules/connman/e_mod_main.c create mode 100644 src/modules/connman/e_mod_main.h create mode 100644 src/modules/connman/module.desktop.in diff --git a/config/.cvsignore b/config/.cvsignore new file mode 100644 index 000000000..cd2c9ce8d --- /dev/null +++ b/config/.cvsignore @@ -0,0 +1,3 @@ +Makefile +Makefile.in +*.cfg diff --git a/config/default/.cvsignore b/config/default/.cvsignore new file mode 100644 index 000000000..cd2c9ce8d --- /dev/null +++ b/config/default/.cvsignore @@ -0,0 +1,3 @@ +Makefile +Makefile.in +*.cfg diff --git a/configure.in b/configure.in index 32195f28a..04a4483e4 100644 --- a/configure.in +++ b/configure.in @@ -434,6 +434,8 @@ src/modules/gadman/Makefile src/modules/gadman/module.desktop src/modules/mixer/Makefile src/modules/mixer/module.desktop +src/modules/connman/Makefile +src/modules/connman/module.desktop src/preload/Makefile data/Makefile data/fonts/Makefile diff --git a/data/themes/Makefile.am b/data/themes/Makefile.am index a03529afa..b7ed1af3c 100644 --- a/data/themes/Makefile.am +++ b/data/themes/Makefile.am @@ -63,7 +63,8 @@ default_fontpreview.edc \ default_wizard.edc \ default_toolbar.edc \ default_slidesel.edc \ -default_mixer.edc +default_mixer.edc \ +default_connman.edc default.edj: Makefile $(EXTRA_DIST) $(EDJE_CC) $(EDJE_FLAGS) \ diff --git a/data/themes/default.edc b/data/themes/default.edc index cf64f43c3..b5662d00d 100644 --- a/data/themes/default.edc +++ b/data/themes/default.edc @@ -87,4 +87,5 @@ collections { #include "default_toolbar.edc" #include "default_slidesel.edc" #include "default_mixer.edc" +#include "default_connman.edc" } diff --git a/data/themes/default_connman.edc b/data/themes/default_connman.edc new file mode 100644 index 000000000..532c06897 --- /dev/null +++ b/data/themes/default_connman.edc @@ -0,0 +1,412 @@ +images { + image: "e17_mixer_base.png" COMP; + image: "e17_mixer_mute.png" COMP; + image: "e17_mixer_left_low.png" COMP; + image: "e17_mixer_left_medium.png" COMP; + image: "e17_mixer_left_high.png" COMP; + image: "e17_mixer_right_low.png" COMP; + image: "e17_mixer_right_medium.png" COMP; + image: "e17_mixer_right_high.png" COMP; +} + +group { + name: "e/modules/connman/main"; + max: 128 128; + min: 1 1; + + script { + public message(Msg_Type:type, id, ...) { + if ((type == MSG_INT_SET) && (id == 0)) { + new sig; + + sig = getarg(2); + + if (sig <= 0) + run_program(PROGRAM:"right_none"); + else if (sig < 33) + run_program(PROGRAM:"right_low"); + else if (sig < 66) + run_program(PROGRAM:"right_medium"); + else if (sig >= 66) + run_program(PROGRAM:"right_high"); + } + } + } + + parts { + part { + name: "base"; + mouse_events: 0; + type: RECT; + description { + state: "default" 0.0; + color: 0 0 0 0; + aspect: 1 1; + aspect_preference: BOTH; + } + } + + part { + name: "speaker"; + mouse_events: 0; + type: IMAGE; + description { + state: "default" 0.0; + aspect: 1 1; + aspect_preference: BOTH; + rel1.to: "base"; + rel2.to: "base"; + image.normal: "e17_mixer_base.png"; + } + } + + part { + name: "left"; + mouse_events: 0; + type: IMAGE; + description { + state: "default" 0.0; + visible: 0; + aspect: 1 1; + aspect_preference: BOTH; + rel1.to: "base"; + rel2.to: "base"; + image.normal: "e17_mixer_left_low.png"; + } + description { + state: "low" 0.0; + inherit: "default" 0.0; + visible: 1; + } + description { + state: "medium" 0.0; + inherit: "default" 0.0; + visible: 1; + image.normal: "e17_mixer_left_medium.png"; + } + description { + state: "high" 0.0; + inherit: "default" 0.0; + visible: 1; + image.normal: "e17_mixer_left_high.png"; + } + } + + part { + name: "right"; + mouse_events: 0; + type: IMAGE; + description { + state: "default" 0.0; + visible: 0; + aspect: 1 1; + aspect_preference: BOTH; + rel1.to: "base"; + rel2.to: "base"; + image.normal: "e17_mixer_right_low.png"; + } + description { + state: "low" 0.0; + inherit: "default" 0.0; + visible: 1; + } + description { + state: "medium" 0.0; + inherit: "default" 0.0; + visible: 1; + image.normal: "e17_mixer_right_medium.png"; + } + description { + state: "high" 0.0; + inherit: "default" 0.0; + visible: 1; + image.normal: "e17_mixer_right_high.png"; + } + } + + part { + name: "mute"; + mouse_events: 0; + type: IMAGE; + description { + state: "default" 0.0; + aspect: 1 1; + aspect_preference: BOTH; + visible: 0; + rel1.to: "base"; + rel2.to: "base"; + image.normal: "e17_mixer_mute.png"; + } + description { + state: "active" 0.0; + inherit: "default" 0.0; + visible: 1; + } + } + + part { + name: "over"; + type: RECT; + description { + state: "default" 0.0; + rel1.to: "base"; + rel2.to: "base"; + color: 255 255 255 0; + } + } + } + + programs { + program { + name: "right_none"; + action: STATE_SET "default" 0.0; + transition: LINEAR 0.1; + target: "right"; + } + + program { + name: "right_low"; + action: STATE_SET "low" 0.0; + transition: LINEAR 0.1; + target: "right"; + } + + program { + name: "right_medium"; + action: STATE_SET "medium" 0.0; + transition: LINEAR 0.1; + target: "right"; + } + + program { + name: "right_high"; + action: STATE_SET "high" 0.0; + transition: LINEAR 0.1; + target: "right"; + } + } +} + +group { + name: "e/modules/connman/network"; + max: 128 128; + min: 1 1; + + script { + public message(Msg_Type:type, id, ...) { + if ((type == MSG_INT_SET) && (id == 1)) { + new sig; + + sig = getarg(2); + + if (sig <= 0) + run_program(PROGRAM:"right_none"); + else if (sig < 33) + run_program(PROGRAM:"right_low"); + else if (sig < 66) + run_program(PROGRAM:"right_medium"); + else if (sig >= 66) + run_program(PROGRAM:"right_high"); + } + } + } + + parts { + part { + name: "base"; + mouse_events: 0; + type: RECT; + description { + state: "default" 0.0; + color: 0 0 0 0; + aspect: 1 1; + aspect_preference: BOTH; + } + } + part { + name: "sec"; + mouse_events: 0; + type: RECT; + description { state: "default" 0.0; + color: 255 255 255 128; + rel2.relative: 0.5 0.5; + } + description { state: "wep" 0.0; + inherit: "default" 0.0; + color: 255 255 0 128; + } + description { state: "wpa" 0.0; + inherit: "default" 0.0; + color: 255 128 0 128; + } + description { state: "rsn" 0.0; + inherit: "default" 0.0; + color: 255 0 0 128; + } + } + + part { + name: "speaker"; + mouse_events: 0; + type: IMAGE; + description { + state: "default" 0.0; + aspect: 1 1; + aspect_preference: BOTH; + rel1.to: "base"; + rel2.to: "base"; + image.normal: "e17_mixer_base.png"; + } + } + + part { + name: "left"; + mouse_events: 0; + type: IMAGE; + description { + state: "default" 0.0; + visible: 0; + aspect: 1 1; + aspect_preference: BOTH; + rel1.to: "base"; + rel2.to: "base"; + image.normal: "e17_mixer_left_low.png"; + } + description { + state: "low" 0.0; + inherit: "default" 0.0; + visible: 1; + } + description { + state: "medium" 0.0; + inherit: "default" 0.0; + visible: 1; + image.normal: "e17_mixer_left_medium.png"; + } + description { + state: "high" 0.0; + inherit: "default" 0.0; + visible: 1; + image.normal: "e17_mixer_left_high.png"; + } + } + + part { + name: "right"; + mouse_events: 0; + type: IMAGE; + description { + state: "default" 0.0; + visible: 0; + aspect: 1 1; + aspect_preference: BOTH; + rel1.to: "base"; + rel2.to: "base"; + image.normal: "e17_mixer_right_low.png"; + } + description { + state: "low" 0.0; + inherit: "default" 0.0; + visible: 1; + } + description { + state: "medium" 0.0; + inherit: "default" 0.0; + visible: 1; + image.normal: "e17_mixer_right_medium.png"; + } + description { + state: "high" 0.0; + inherit: "default" 0.0; + visible: 1; + image.normal: "e17_mixer_right_high.png"; + } + } + + part { + name: "mute"; + mouse_events: 0; + type: IMAGE; + description { + state: "default" 0.0; + aspect: 1 1; + aspect_preference: BOTH; + visible: 0; + rel1.to: "base"; + rel2.to: "base"; + image.normal: "e17_mixer_mute.png"; + } + description { + state: "active" 0.0; + inherit: "default" 0.0; + visible: 1; + } + } + + part { + name: "over"; + type: RECT; + description { + state: "default" 0.0; + rel1.to: "base"; + rel2.to: "base"; + color: 255 255 255 0; + } + } + } + + programs { + program { + name: "right_none"; + action: STATE_SET "default" 0.0; + transition: LINEAR 0.1; + target: "right"; + + } + program { + name: "right_low"; + action: STATE_SET "low" 0.0; + transition: LINEAR 0.1; + target: "right"; + } + + program { + name: "right_medium"; + action: STATE_SET "medium" 0.0; + transition: LINEAR 0.1; + target: "right"; + } + + program { + name: "right_high"; + action: STATE_SET "high" 0.0; + transition: LINEAR 0.1; + target: "right"; + } + + program { name: "sec0"; + signal: "s,state,security,open"; + source: "e"; + action: STATE_SET "default" 0.0; + target: "sec"; + } + program { name: "sec1"; + signal: "s,state,security,wep"; + source: "e"; + action: STATE_SET "wep" 0.0; + target: "sec"; + } + program { name: "sec2"; + signal: "s,state,security,wpa"; + source: "e"; + action: STATE_SET "wpa" 0.0; + target: "sec"; + } + program { name: "sec3"; + signal: "s,state,security,rsn"; + source: "e"; + action: STATE_SET "rsn" 0.0; + target: "sec"; + } + } +} diff --git a/src/modules/Makefile.am b/src/modules/Makefile.am index 19d0fb10b..a4512a9ec 100644 --- a/src/modules/Makefile.am +++ b/src/modules/Makefile.am @@ -52,7 +52,8 @@ conf_mime \ conf_interaction \ gadman \ mixer \ -conf_window_remembers +conf_window_remembers \ +connman if HAVE_TEMPERATURE SUBDIRS += temperature diff --git a/src/modules/connman/.cvsignore b/src/modules/connman/.cvsignore new file mode 100644 index 000000000..91e51953a --- /dev/null +++ b/src/modules/connman/.cvsignore @@ -0,0 +1,9 @@ +.deps +.libs +Makefile +Makefile.in +e_mod_main.lo +module.la +*.lo +*.la +module.desktop diff --git a/src/modules/connman/Makefile.am b/src/modules/connman/Makefile.am new file mode 100644 index 000000000..be48417b8 --- /dev/null +++ b/src/modules/connman/Makefile.am @@ -0,0 +1,33 @@ +MAINTAINERCLEANFILES = Makefile.in +MODULE = connman + +# data files for the module +filesdir = $(libdir)/enlightenment/modules/$(MODULE) +files_DATA = \ +e-module-$(MODULE).edj module.desktop + +EXTRA_DIST = $(files_DATA) + +# the module .so file +INCLUDES = -I. \ + -I$(top_srcdir) \ + -I$(top_srcdir)/src/modules/$(MODULE) \ + -I$(top_srcdir)/src/bin \ + -I$(top_srcdir)/src/lib \ + -I$(top_srcdir)/src/modules \ + @e_cflags@ + +pkgdir = $(libdir)/enlightenment/modules/$(MODULE)/$(MODULE_ARCH) +pkg_LTLIBRARIES = module.la + +module_la_SOURCES = e_mod_main.h \ + e_mod_main.c \ + e_iface.h \ + e_iface.c + +module_la_LIBADD = @e_libs@ @dlopen_libs@ @E_DBUS_LIBS@ +module_la_LDFLAGS = -module -avoid-version +module_la_DEPENDENCIES = $(top_builddir)/config.h + +uninstall: + rm -rf $(DESTDIR)$(libdir)/enlightenment/modules/$(MODULE) diff --git a/src/modules/connman/e-module-connman.edj b/src/modules/connman/e-module-connman.edj new file mode 100644 index 0000000000000000000000000000000000000000..743f6a3f65c26ac32c675781c519bb058b2eff4d GIT binary patch literal 8255 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 Yq+(Qo(R{Vf!DQ@exqqm|V{+~P1DMy)d;kCd literal 0 HcmV?d00001 diff --git a/src/modules/connman/e_iface.c b/src/modules/connman/e_iface.c new file mode 100644 index 000000000..d570ad917 --- /dev/null +++ b/src/modules/connman/e_iface.c @@ -0,0 +1,1348 @@ +#include "e_iface.h" + +/* IFACE INTERNALS */ +static E_DBus_Connection *conn = NULL; +static Evas_List *callbacks = NULL; +static E_DBus_Signal_Handler *sigh_name_ownerchanged = NULL; +static E_DBus_Signal_Handler *sigh_interface_added = NULL; +static E_DBus_Signal_Handler *sigh_interface_removed = NULL; +static Evas_List *interfaces = NULL; + +static Evas_List * +iface_callback(Evas_List *callbacks, Interface_Event event, Interface *iface, Interface_Network *ifnet) +{ + Evas_List *l; + Evas_List *deletes = NULL; + + for (l = callbacks; l; l = l->next) + { + Interface_Callback *cb; + + cb = l->data; + if (cb->delete_me) + { + deletes = evas_list_append(deletes, l->data); + continue; + } + if (cb->event == event) + cb->func(cb->data, iface, ifnet); + } + while (deletes) + { + callbacks = evas_list_remove(callbacks, deletes->data); + free(deletes->data); + deletes = evas_list_remove_list(deletes, deletes); + } + return callbacks; +} + +static Interface_IPv4 * +iface_ipv4_decode(DBusMessage *msg) +{ + DBusMessageIter array, iter, item, val; + Interface_IPv4 *d; + + d = calloc(1, sizeof(Interface_IPv4)); + if (!d) return NULL; + + if (dbus_message_iter_init(msg, &array)) + { + if (dbus_message_iter_get_arg_type(&array) == DBUS_TYPE_ARRAY) + { + dbus_message_iter_recurse(&array, &iter); + while (dbus_message_iter_get_arg_type(&iter) == DBUS_TYPE_DICT_ENTRY) + { + char *key, *v; + int sig; + int type; + + dbus_message_iter_recurse(&iter, &item); + key = NULL; + dbus_message_iter_get_basic(&item, &key); + dbus_message_iter_next(&item); + dbus_message_iter_recurse(&item, &val); + type = dbus_message_iter_get_arg_type(&val); + v = NULL; + if ((!strcmp(key, "Method")) && (type == DBUS_TYPE_STRING)) + { + dbus_message_iter_get_basic(&val, &v); + if (v) d->method = evas_stringshare_add(v); + } + else if ((!strcmp(key, "Address")) && (type == DBUS_TYPE_STRING)) + { + dbus_message_iter_get_basic(&val, &v); + if (v) d->address = evas_stringshare_add(v); + } + else if ((!strcmp(key, "Gateway")) && (type == DBUS_TYPE_STRING)) + { + dbus_message_iter_get_basic(&val, &v); + if (v) d->gateway = evas_stringshare_add(v); + } + else if ((!strcmp(key, "Netmask")) && (type == DBUS_TYPE_STRING)) + { + dbus_message_iter_get_basic(&val, &v); + if (v) d->netmask = evas_stringshare_add(v); + } + dbus_message_iter_next(&iter); + } + } + } + return d; +} + +static void * +iface_getipv4_unmarhsall(DBusMessage *msg, DBusError *err) +{ + return iface_ipv4_decode(msg); +} + +static void +iface_getipv4_callback(void *data, void *ret, DBusError *err) +{ + Interface *iface = data; + Interface_IPv4 *d = ret; + + if (!d) + { + iface_unref(iface); + return; + } + if (iface->ipv4.method) evas_stringshare_del(iface->ipv4.method); + if (iface->ipv4.address) evas_stringshare_del(iface->ipv4.address); + if (iface->ipv4.gateway) evas_stringshare_del(iface->ipv4.gateway); + if (iface->ipv4.netmask) evas_stringshare_del(iface->ipv4.netmask); + memcpy(&(iface->ipv4), d, sizeof(Interface_IPv4)); + iface->callbacks = iface_callback(iface->callbacks, + IFACE_EVENT_IPV4_CHANGE, + iface, NULL); + iface_unref(iface); +} + +static void +iface_getipv4_result_free(void *data) +{ + Interface_IPv4 *d = data; + free(d); +} + +static Interface_Network_Selection * +iface_network_selection_decode(DBusMessage *msg) +{ + DBusMessageIter array, iter, item, val; + Interface_Network_Selection *d; + + d = calloc(1, sizeof(Interface_Network_Selection)); + if (!d) return NULL; + + if (dbus_message_iter_init(msg, &array)) + { + if (dbus_message_iter_get_arg_type(&array) == DBUS_TYPE_ARRAY) + { + dbus_message_iter_recurse(&array, &iter); + while (dbus_message_iter_get_arg_type(&iter) == DBUS_TYPE_DICT_ENTRY) + { + char *key, *v; + int sig; + int type; + + dbus_message_iter_recurse(&iter, &item); + key = NULL; + dbus_message_iter_get_basic(&item, &key); + dbus_message_iter_next(&item); + dbus_message_iter_recurse(&item, &val); + type = dbus_message_iter_get_arg_type(&val); + v = NULL; + if ((!strcmp(key, "ESSID")) && (type == DBUS_TYPE_STRING)) + { + dbus_message_iter_get_basic(&val, &v); + if (v) d->id = evas_stringshare_add(v); + } + else if ((!strcmp(key, "PSK")) && (type == DBUS_TYPE_STRING)) + { + dbus_message_iter_get_basic(&val, &v); + if (v) d->pass = evas_stringshare_add(v); + } + dbus_message_iter_next(&iter); + } + } + } + return d; +} + +static void * +iface_getnetwork_unmarhsall(DBusMessage *msg, DBusError *err) +{ + return iface_network_selection_decode(msg); +} + +static void +iface_getnetwork_callback(void *data, void *ret, DBusError *err) +{ + Interface *iface = data; + Interface_Network_Selection *d = ret; + + if (!d) + { + iface_unref(iface); + return; + } + if (iface->network_selection.id) evas_stringshare_del(iface->network_selection.id); + if (iface->network_selection.pass) evas_stringshare_del(iface->network_selection.pass); + memcpy(&(iface->network_selection), d, sizeof(Interface_Network_Selection)); + iface->callbacks = iface_callback(iface->callbacks, + IFACE_EVENT_NETWORK_SELECTION_CHANGE, + iface, NULL); + iface_unref(iface); +} + +static void +iface_getnetwork_result_free(void *data) +{ + Interface_IPv4 *d = data; + free(d); +} + +static void * +iface_getproperties_unmarhsall(DBusMessage *msg, DBusError *err) +{ + DBusMessageIter array, iter, item, val; + Interface_Properties *d; + + d = calloc(1, sizeof(Interface_Properties)); + if (!d) return NULL; + + if (dbus_message_iter_init(msg, &array)) + { + if (dbus_message_iter_get_arg_type(&array) == DBUS_TYPE_ARRAY) + { + dbus_message_iter_recurse(&array, &iter); + while (dbus_message_iter_get_arg_type(&iter) == DBUS_TYPE_DICT_ENTRY) + { + char *key, *v; + int sig; + int type; + + dbus_message_iter_recurse(&iter, &item); + key = NULL; + dbus_message_iter_get_basic(&item, &key); + dbus_message_iter_next(&item); + dbus_message_iter_recurse(&item, &val); + type = dbus_message_iter_get_arg_type(&val); + v = NULL; + if ((!strcmp(key, "Type")) && (type == DBUS_TYPE_STRING)) + { + dbus_message_iter_get_basic(&val, &v); + if (v) d->type = evas_stringshare_add(v); + } + else if ((!strcmp(key, "State")) && (type == DBUS_TYPE_STRING)) + { + dbus_message_iter_get_basic(&val, &v); + if (v) d->state = evas_stringshare_add(v); + } + else if ((!strcmp(key, "Policy")) && (type == DBUS_TYPE_STRING)) + { + dbus_message_iter_get_basic(&val, &v); + if (v) d->policy = evas_stringshare_add(v); + } + else if ((!strcmp(key, "Driver")) && (type == DBUS_TYPE_STRING)) + { + dbus_message_iter_get_basic(&val, &v); + if (v) d->driver = evas_stringshare_add(v); + } + else if ((!strcmp(key, "Vendor")) && (type == DBUS_TYPE_STRING)) + { + dbus_message_iter_get_basic(&val, &v); + if (v) d->vendor = evas_stringshare_add(v); + } + else if ((!strcmp(key, "Product")) && (type == DBUS_TYPE_STRING)) + { + dbus_message_iter_get_basic(&val, &v); + if (v) d->product = evas_stringshare_add(v); + } + else if ((!strcmp(key, "Signal")) && (type == DBUS_TYPE_UINT16)) + { + dbus_uint16_t vi; + dbus_message_iter_get_basic(&val, &vi); + d->signal_strength = vi; + } + dbus_message_iter_next(&iter); + } + } + } + return d; +} + +static void +iface_getproperties_callback(void *data, void *ret, DBusError *err) +{ + Interface *iface = data; + Interface_Properties *d = ret; + if (!d) + { + iface_unref(iface); + iface_unref(iface); + return; + } + if (iface->prop.product) evas_stringshare_del(iface->prop.product); + if (iface->prop.vendor) evas_stringshare_del(iface->prop.vendor); + if (iface->prop.driver) evas_stringshare_del(iface->prop.driver); + if (iface->prop.state) evas_stringshare_del(iface->prop.state); + if (iface->prop.policy) evas_stringshare_del(iface->prop.policy); + if (iface->prop.type) evas_stringshare_del(iface->prop.type); + memcpy(&(iface->prop), d, sizeof(Interface_Properties)); + if (!iface->newif) + { + callbacks = iface_callback(callbacks, + IFACE_EVENT_ADD, + iface, NULL); + iface->newif = 1; + } + iface_unref(iface); +} + +static void +iface_getproperties_result_free(void *data) +{ + Interface_Properties *d = data; + free(d); +} + +static void +iface_net_add(Interface *iface, const char *essid, const char *bssid, int signal_strength, const char *security) +{ + Interface_Network *net; + Evas_List *l; + + for (l = iface->networks; l; l = l->next) + { + net = l->data; + if (!strcmp(bssid, net->bssid)) + { + int changes = 0; + + net->last_seen_time = ecore_time_get(); + if (((essid) && (net->essid) && + (!strcmp(essid, net->essid))) || + (!!essid != !!net->essid)) + { + if (net->essid) evas_stringshare_del(net->essid); + if (essid) net->essid = evas_stringshare_add(essid); + else net->essid = NULL; + changes++; + } + if (signal_strength != net->signal_strength) + { + net->signal_strength = signal_strength; + changes++; + } + if (((security) && (net->security) && + (!strcmp(security, net->security))) || + (!!security != !!net->security)) + { + if (net->security) evas_stringshare_del(net->security); + if (security) net->security = evas_stringshare_add(security); + else net->security = NULL; + changes++; + } + if (changes > 0) + iface->callbacks = iface_callback(iface->callbacks, + IFACE_EVENT_SCAN_NETWORK_CHANGE, + iface, net); + return; + } + } + net = calloc(1, sizeof(Interface_Network)); + if (net) + { + net->last_seen_time = ecore_time_get(); + if (essid) net->essid = evas_stringshare_add(essid); + net->bssid = evas_stringshare_add(bssid); + net->signal_strength = signal_strength; + if (security) net->security = evas_stringshare_add(security); + iface->networks = evas_list_append(iface->networks, net); + iface->callbacks = iface_callback(iface->callbacks, + IFACE_EVENT_SCAN_NETWORK_ADD, + iface, net); + } +} + +static void +iface_sigh_network_found(void *data, DBusMessage *msg) +{ + DBusError err; + Interface *iface = data; + DBusMessageIter array, iter, item, val; + Interface_Properties *d; + + if (dbus_message_iter_init(msg, &array)) + { + if (dbus_message_iter_get_arg_type(&array) == DBUS_TYPE_ARRAY) + { + Interface_Network *net; + + dbus_message_iter_recurse(&array, &iter); + net = calloc(1, sizeof(Interface_Network)); + if (net) + { + while (dbus_message_iter_get_arg_type(&iter) == DBUS_TYPE_DICT_ENTRY) + { + char *key, *v; + int type; + + dbus_message_iter_recurse(&iter, &item); + key = NULL; + dbus_message_iter_get_basic(&item, &key); + dbus_message_iter_next(&item); + dbus_message_iter_recurse(&item, &val); + type = dbus_message_iter_get_arg_type(&val); + v = NULL; + if ((!strcmp(key, "ESSID")) && (type == DBUS_TYPE_STRING)) + { + dbus_message_iter_get_basic(&val, &v); + if (v) net->essid = evas_stringshare_add(v); + } + else if ((!strcmp(key, "BSSID")) && (type == DBUS_TYPE_STRING)) + { + dbus_message_iter_get_basic(&val, &v); + if (v) net->bssid = evas_stringshare_add(v); + } + else if ((!strcmp(key, "Signal")) && (type == DBUS_TYPE_UINT16)) + { + dbus_uint16_t vi; + dbus_message_iter_get_basic(&val, &vi); + net->signal_strength = vi; + } + if ((!strcmp(key, "Security")) && (type == DBUS_TYPE_STRING)) + { + dbus_message_iter_get_basic(&val, &v); + if (v) net->security = evas_stringshare_add(v); + } + dbus_message_iter_next(&iter); + } + if (net->bssid) + iface_net_add(iface, net->essid, net->bssid, + net->signal_strength, net->security); + if (net->essid) evas_stringshare_del(net->essid); + if (net->bssid) evas_stringshare_del(net->bssid); + if (net->security) evas_stringshare_del(net->security); + free(net); + } + } + } +} + +static void +iface_sigh_signal_changed(void *data, DBusMessage *msg) +{ + DBusError err; + Interface *iface = data; + + /* FIXME: need to handle signal changed - and fix connman */ + /* FIXME: wpa_supplicant doesn't support this yet. see: + * mlme.c: ieee80211_associated() */ + iface->callbacks = iface_callback(iface->callbacks, + IFACE_EVENT_SIGNAL_CHANGE, + iface, NULL); +} + +static void +iface_sigh_state_changed(void *data, DBusMessage *msg) +{ + DBusError err; + Interface *iface = data; + DBusMessageIter iter; + const char *s = NULL; + + dbus_message_iter_init(msg, &iter); + dbus_message_iter_get_basic(&iter, &(s)); + if (!s) return; + if (iface->prop.state) evas_stringshare_del(iface->prop.state); + iface->prop.state = evas_stringshare_add(s); + + msg = dbus_message_new_method_call("org.freedesktop.connman", + iface->ifpath, + "org.freedesktop.connman.Interface", + "GetIPv4"); + if (msg) + { + e_dbus_method_call_send(conn, msg, + iface_getipv4_unmarhsall, + iface_getipv4_callback, + iface_getipv4_result_free, -1, iface); + dbus_message_unref(msg); + iface_ref(iface); + } + iface->callbacks = iface_callback(iface->callbacks, + IFACE_EVENT_STATE_CHANGE, + iface, NULL); +} + +static void +iface_sigh_policy_changed(void *data, DBusMessage *msg) +{ + DBusError err; + Interface *iface = data; + DBusMessageIter iter; + const char *s = NULL; + + dbus_message_iter_init(msg, &iter); + dbus_message_iter_get_basic(&iter, &(s)); + if (!s) return; + if (iface->prop.policy) evas_stringshare_del(iface->prop.policy); + iface->prop.policy = evas_stringshare_add(s); + iface->callbacks = iface_callback(iface->callbacks, + IFACE_EVENT_POLICY_CHANGE, + iface, NULL); +} + +static void +iface_sigh_network_changed(void *data, DBusMessage *msg) +{ + DBusError err; + Interface *iface = data; + Interface_Network_Selection *d; + + d = iface_network_selection_decode(msg); + if (!d) return; + + if (iface->network_selection.id) evas_stringshare_del(iface->network_selection.id); + if (iface->network_selection.pass) evas_stringshare_del(iface->network_selection.pass); + memcpy(&(iface->network_selection), d, sizeof(Interface_Network_Selection)); + free(d); + iface->callbacks = iface_callback(iface->callbacks, + IFACE_EVENT_NETWORK_SELECTION_CHANGE, + iface, NULL); +} + +static void +iface_sigh_ipv4_changed(void *data, DBusMessage *msg) +{ + DBusError err; + Interface *iface = data; + Interface_IPv4 *d; + + d = iface_ipv4_decode(msg); + if (!d) return; + + if (iface->ipv4.method) evas_stringshare_del(iface->ipv4.method); + if (iface->ipv4.address) evas_stringshare_del(iface->ipv4.address); + if (iface->ipv4.gateway) evas_stringshare_del(iface->ipv4.gateway); + if (iface->ipv4.netmask) evas_stringshare_del(iface->ipv4.netmask); + memcpy(&(iface->ipv4), d, sizeof(Interface_IPv4)); + free(d); + iface->callbacks = iface_callback(iface->callbacks, + IFACE_EVENT_IPV4_CHANGE, + iface, NULL); +} + +static int +iface_timer_network_timeout(void *data) +{ + Interface *iface = data; + double now; + Interface_Network *net; + Evas_List *l, *l_del; + + now = ecore_time_get(); + iface_ref(iface); + for (l = iface->networks; l;) + { + net = l->data; + if ((now - net->last_seen_time) > 20.0) + { + l_del = l; + l = l->next; + iface->callbacks = iface_callback(iface->callbacks, + IFACE_EVENT_SCAN_NETWORK_DEL, + iface, net); + iface->networks = evas_list_remove_list(iface->networks, l_del); + if (net->essid) evas_stringshare_del(net->essid); + if (net->bssid) evas_stringshare_del(net->bssid); + if (net->security) evas_stringshare_del(net->security); + free(net); + } + else + l = l->next; + } + iface_unref(iface); +} + +static void * +iface_system_listinterfaces_unmarhsall(DBusMessage *msg, DBusError *err) +{ + DBusMessageIter array, iter; + + if (dbus_message_iter_init(msg, &array)) + { + if (dbus_message_iter_get_arg_type(&array) == DBUS_TYPE_ARRAY) + { + dbus_message_iter_recurse(&array, &iter); + do + { + char *ifpath; + + ifpath = NULL; + dbus_message_iter_get_basic(&iter, &ifpath); + if (ifpath) + { + if (!iface_find(ifpath)) + { + printf("ADD 1 %s\n", ifpath); + iface_add(ifpath); + } + } + } + while (dbus_message_iter_next(&iter)); + } + } + return NULL; +} + +static void +iface_system_listinterfaces_callback(void *data, void *ret, DBusError *err) +{ +} + +static void +iface_system_listinterfaces_result_free(void *data) +{ +} + +static void +iface_system_added(void *data, DBusMessage *msg) +{ + DBusError err; + DBusMessageIter iter; + const char *s = NULL; + + dbus_message_iter_init(msg, &iter); + dbus_message_iter_get_basic(&iter, &(s)); + if (!s) return; + if (iface_find(s)) return; + printf("ADD 2 %s\n", s); + iface_add(s); +} + +static void +iface_system_removed(void *data, DBusMessage *msg) +{ + DBusError err; + DBusMessageIter iter; + const char *s = NULL; + Interface *iface; + + dbus_message_iter_init(msg, &iter); + dbus_message_iter_get_basic(&iter, &(s)); + if (!s) return; + if (!(iface = iface_find(s))) return; + callbacks = iface_callback(callbacks, + IFACE_EVENT_DEL, + iface, NULL); + iface_unref(iface); +} + +static void +iface_system_interfaces_list(void) +{ + DBusMessage *msg; + + msg = dbus_message_new_method_call("org.freedesktop.connman", + "/", + "org.freedesktop.connman.Manager", + "ListInterfaces"); + if (!msg) return; + e_dbus_method_call_send(conn, msg, + iface_system_listinterfaces_unmarhsall, + iface_system_listinterfaces_callback, + iface_system_listinterfaces_result_free, -1, NULL); + dbus_message_unref(msg); + + if (sigh_interface_added) + e_dbus_signal_handler_del(conn, sigh_interface_added); + sigh_interface_added = e_dbus_signal_handler_add + (conn, "org.freedesktop.connman", "/", "org.freedesktop.connman.Manager", + "InterfaceAdded", iface_system_added, NULL); + if (sigh_interface_removed) + e_dbus_signal_handler_del(conn, sigh_interface_removed); + sigh_interface_removed = e_dbus_signal_handler_add + (conn, "org.freedesktop.connman", "/", "org.freedesktop.connman.Manager", + "InterfaceRemoved", iface_system_removed, NULL); +} + +static void +iface_system_name_ownerchanged(void *data, DBusMessage *msg) +{ + DBusError err; + DBusMessageIter iter; + const char *s1, *s2, *s3; + + dbus_error_init(&err); + if (!dbus_message_get_args(msg, &err, + DBUS_TYPE_STRING, &s1, + DBUS_TYPE_STRING, &s2, + DBUS_TYPE_STRING, &s3, + DBUS_TYPE_INVALID)) + return; + if (strcmp(s1, "org.freedesktop.connman")) return; + iface_system_interfaces_list(); +} + +/* IFACE PUBLIC API */ +Interface * +iface_add(const char *ifpath) +{ + Interface *iface; + DBusMessage *msg; + + iface = calloc(1, sizeof(Interface)); + iface->ref = 1; + iface->ifpath = evas_stringshare_add(ifpath); + + msg = dbus_message_new_method_call("org.freedesktop.connman", + iface->ifpath, + "org.freedesktop.connman.Interface", + "GetProperties"); + if (!msg) + { + evas_stringshare_del(iface->ifpath); + free(iface); + return NULL; + } + e_dbus_method_call_send(conn, msg, + iface_getproperties_unmarhsall, + iface_getproperties_callback, + iface_getproperties_result_free, -1, iface); + dbus_message_unref(msg); + iface_ref(iface); + + msg = dbus_message_new_method_call("org.freedesktop.connman", + iface->ifpath, + "org.freedesktop.connman.Interface", + "GetIPv4"); + if (msg) + { + e_dbus_method_call_send(conn, msg, + iface_getipv4_unmarhsall, + iface_getipv4_callback, + iface_getipv4_result_free, -1, iface); + dbus_message_unref(msg); + iface_ref(iface); + } + + msg = dbus_message_new_method_call("org.freedesktop.connman", + iface->ifpath, + "org.freedesktop.connman.Interface", + "GetNetwork"); + if (msg) + { + e_dbus_method_call_send(conn, msg, + iface_getnetwork_unmarhsall, + iface_getnetwork_callback, + iface_getnetwork_result_free, -1, iface); + dbus_message_unref(msg); + iface_ref(iface); + } + + iface->sigh.network_found = e_dbus_signal_handler_add + (conn, "org.freedesktop.connman", iface->ifpath, + "org.freedesktop.connman.Interface", "NetworkFound", + iface_sigh_network_found, iface); + iface->sigh.signal_changed = e_dbus_signal_handler_add + (conn, "org.freedesktop.connman", iface->ifpath, + "org.freedesktop.connman.Interface", "SignalChanged", + iface_sigh_signal_changed, iface); + iface->sigh.state_changed = e_dbus_signal_handler_add + (conn, "org.freedesktop.connman", iface->ifpath, + "org.freedesktop.connman.Interface", "StateChanged", + iface_sigh_state_changed, iface); + iface->sigh.policy_changed = e_dbus_signal_handler_add + (conn, "org.freedesktop.connman", iface->ifpath, + "org.freedesktop.connman.Interface", "PolicyChanged", + iface_sigh_policy_changed, iface); + iface->sigh.network_changed = e_dbus_signal_handler_add + (conn, "org.freedesktop.connman", iface->ifpath, + "org.freedesktop.connman.Interface", "NetworkChanged", + iface_sigh_network_changed, iface); + iface->sigh.ipv4_changed = e_dbus_signal_handler_add + (conn, "org.freedesktop.connman", iface->ifpath, + "org.freedesktop.connman.Interface", "IPv4Changed", + iface_sigh_ipv4_changed, iface); + + iface->network_timeout = ecore_timer_add(10.0, iface_timer_network_timeout, + iface); + interfaces = evas_list_append(interfaces, iface); + return iface; +} + +void +iface_ref(Interface *iface) +{ + iface->ref++; +} + +void +iface_unref(Interface *iface) +{ + iface->ref--; + if (iface->ref != 0) return; + + iface->callbacks = iface_callback(iface->callbacks, + IFACE_EVENT_DEL, + iface, NULL); + + while (iface->callbacks) + { + free(iface->callbacks->data); + iface->callbacks = evas_list_remove_list(iface->callbacks, iface->callbacks); + } + + if (iface->network_timeout) + ecore_timer_del(iface->network_timeout); + if (iface->network_selection.id) evas_stringshare_del(iface->network_selection.id); + if (iface->network_selection.pass) evas_stringshare_del(iface->network_selection.pass); + while (iface->networks) + { + Interface_Network *net; + + net = iface->networks->data; + if (net->essid) evas_stringshare_del(net->essid); + if (net->bssid) evas_stringshare_del(net->bssid); + if (net->security) evas_stringshare_del(net->security); + free(net); + iface->networks = evas_list_remove_list(iface->networks, iface->networks); + } + if (iface->network_timeout) ecore_timer_del(iface->network_timeout); + if (iface->prop.product) evas_stringshare_del(iface->prop.product); + if (iface->prop.vendor) evas_stringshare_del(iface->prop.vendor); + if (iface->prop.driver) evas_stringshare_del(iface->prop.driver); + if (iface->prop.state) evas_stringshare_del(iface->prop.state); + if (iface->prop.policy) evas_stringshare_del(iface->prop.policy); + if (iface->prop.type) evas_stringshare_del(iface->prop.type); + e_dbus_signal_handler_del(conn, iface->sigh.network_found); + e_dbus_signal_handler_del(conn, iface->sigh.signal_changed); + e_dbus_signal_handler_del(conn, iface->sigh.state_changed); + e_dbus_signal_handler_del(conn, iface->sigh.policy_changed); + e_dbus_signal_handler_del(conn, iface->sigh.network_changed); + e_dbus_signal_handler_del(conn, iface->sigh.ipv4_changed); + interfaces = evas_list_remove(interfaces, iface); + free(iface); +} + +Interface * +iface_find(const char *ifpath) +{ + Evas_List *l; + + if (!ifpath) return NULL; + for (l = interfaces; l; l = l->next) + { + Interface *iface; + + iface = l->data; + if (!strcmp(iface->ifpath, ifpath)) return iface; + } + return NULL; +} + +void +iface_network_set(Interface *iface, const char *ssid, const char *pass) +{ + DBusMessage *msg; + DBusMessageIter iter, array, item, val; + const char *key; + + msg = dbus_message_new_method_call("org.freedesktop.connman", + iface->ifpath, + "org.freedesktop.connman.Interface", + "SetNetwork"); + if (!msg) return; + dbus_message_iter_init_append(msg, &iter); + dbus_message_iter_open_container(&iter, DBUS_TYPE_ARRAY, + DBUS_DICT_ENTRY_BEGIN_CHAR_AS_STRING + DBUS_TYPE_STRING_AS_STRING + DBUS_TYPE_VARIANT_AS_STRING + DBUS_DICT_ENTRY_END_CHAR_AS_STRING, &array); + + dbus_message_iter_open_container(&array, DBUS_TYPE_DICT_ENTRY, NULL, &item); + key = "ESSID"; + dbus_message_iter_append_basic(&item, DBUS_TYPE_STRING, &key); + dbus_message_iter_open_container(&item, DBUS_TYPE_VARIANT, DBUS_TYPE_STRING_AS_STRING, &val); + dbus_message_iter_append_basic(&val, DBUS_TYPE_STRING, &ssid); + dbus_message_iter_close_container(&item, &val); + dbus_message_iter_close_container(&array, &item); + + if (pass) + { + dbus_message_iter_open_container(&array, DBUS_TYPE_DICT_ENTRY, NULL, &item); + key = "PSK"; + dbus_message_iter_append_basic(&item, DBUS_TYPE_STRING, &key); + dbus_message_iter_open_container(&item, DBUS_TYPE_VARIANT, DBUS_TYPE_STRING_AS_STRING, &val); + dbus_message_iter_append_basic(&val, DBUS_TYPE_STRING, &pass); + dbus_message_iter_close_container(&item, &val); + dbus_message_iter_close_container(&array, &item); + } + + dbus_message_iter_close_container(&iter, &array); + + e_dbus_method_call_send(conn, msg, NULL, NULL, NULL, -1, NULL); + dbus_message_unref(msg); +} + +void +iface_policy_set(Interface *iface, const char *policy) +{ + DBusMessage *msg; + DBusMessageIter iter; + + msg = dbus_message_new_method_call("org.freedesktop.connman", + iface->ifpath, + "org.freedesktop.connman.Interface", + "SetPolicy"); + if (!msg) return; + dbus_message_iter_init_append(msg, &iter); + dbus_message_iter_append_basic(&iter, DBUS_TYPE_STRING, &policy); + + e_dbus_method_call_send(conn, msg, NULL, NULL, NULL, -1, NULL); + dbus_message_unref(msg); +} + +void +iface_scan(Interface *iface, const char *policy) +{ + DBusMessage *msg; + + msg = dbus_message_new_method_call("org.freedesktop.connman", + iface->ifpath, + "org.freedesktop.connman.Interface", + "Scan"); + if (!msg) return; + e_dbus_method_call_send(conn, msg, NULL, NULL, NULL, -1, NULL); + dbus_message_unref(msg); +} + +void +iface_ipv4_set(Interface *iface, const char *method, const char *address, const char *gateway, const char *netmask) +{ + DBusMessage *msg; + DBusMessageIter iter, array, item, val; + const char *key; + + msg = dbus_message_new_method_call("org.freedesktop.connman", + iface->ifpath, + "org.freedesktop.connman.Interface", + "SetIPv4"); + if (!msg) return; + dbus_message_iter_init_append(msg, &iter); + dbus_message_iter_open_container(&iter, DBUS_TYPE_ARRAY, + DBUS_DICT_ENTRY_BEGIN_CHAR_AS_STRING + DBUS_TYPE_STRING_AS_STRING + DBUS_TYPE_VARIANT_AS_STRING + DBUS_DICT_ENTRY_END_CHAR_AS_STRING, &array); + + if (method) + { + dbus_message_iter_open_container(&array, DBUS_TYPE_DICT_ENTRY, NULL, &item); + key = "Method"; + dbus_message_iter_append_basic(&item, DBUS_TYPE_STRING, &key); + dbus_message_iter_open_container(&item, DBUS_TYPE_VARIANT, DBUS_TYPE_STRING_AS_STRING, &val); + dbus_message_iter_append_basic(&val, DBUS_TYPE_STRING, &method); + dbus_message_iter_close_container(&item, &val); + dbus_message_iter_close_container(&array, &item); + } + + if (address) + { + dbus_message_iter_open_container(&array, DBUS_TYPE_DICT_ENTRY, NULL, &item); + key = "Address"; + dbus_message_iter_append_basic(&item, DBUS_TYPE_STRING, &key); + dbus_message_iter_open_container(&item, DBUS_TYPE_VARIANT, DBUS_TYPE_STRING_AS_STRING, &val); + dbus_message_iter_append_basic(&val, DBUS_TYPE_STRING, &address); + dbus_message_iter_close_container(&item, &val); + dbus_message_iter_close_container(&array, &item); + } + + if (gateway) + { + dbus_message_iter_open_container(&array, DBUS_TYPE_DICT_ENTRY, NULL, &item); + key = "Gateway"; + dbus_message_iter_append_basic(&item, DBUS_TYPE_STRING, &key); + dbus_message_iter_open_container(&item, DBUS_TYPE_VARIANT, DBUS_TYPE_STRING_AS_STRING, &val); + dbus_message_iter_append_basic(&val, DBUS_TYPE_STRING, &gateway); + dbus_message_iter_close_container(&item, &val); + dbus_message_iter_close_container(&array, &item); + } + + if (netmask) + { + dbus_message_iter_open_container(&array, DBUS_TYPE_DICT_ENTRY, NULL, &item); + key = "Netmask"; + dbus_message_iter_append_basic(&item, DBUS_TYPE_STRING, &key); + dbus_message_iter_open_container(&item, DBUS_TYPE_VARIANT, DBUS_TYPE_STRING_AS_STRING, &val); + dbus_message_iter_append_basic(&val, DBUS_TYPE_STRING, &netmask); + dbus_message_iter_close_container(&item, &val); + dbus_message_iter_close_container(&array, &item); + } + + dbus_message_iter_close_container(&iter, &array); + + e_dbus_method_call_send(conn, msg, NULL, NULL, NULL, -1, NULL); + dbus_message_unref(msg); +} + +void +iface_callback_add(Interface *iface, Interface_Event event, void (*func) (void *data, Interface *iface, Interface_Network *ifnet), void *data) +{ + Interface_Callback *cb; + + cb = calloc(1, sizeof(Interface_Callback)); + if (!cb) return; + cb->event = event; + cb->func = func; + cb->data = data; + iface->callbacks = evas_list_append(iface->callbacks, cb); +} + +void +iface_callback_del(Interface *iface, Interface_Event event, void (*func) (void *data, Interface *iface, Interface_Network *ifnet), void *data) +{ + Evas_List *l; + + for (l = iface->callbacks; l; l = l->next) + { + Interface_Callback *cb; + + cb = l->data; + if ((cb->event == event) && (cb->func == func) && (cb->data == data)) + { + /* just flag for deletion - cleanup happens later */ + cb->delete_me = 1; + return; + } + } +} + +void +iface_system_init(E_DBus_Connection *edbus_conn) +{ + conn = edbus_conn; + /* init iface system - listen for connman name owner change - if we get it + * connman was sarted or restarted this handles connman starting later + * than the front-end gui */ + sigh_name_ownerchanged = e_dbus_signal_handler_add + (conn, "org.freedesktop.DBus", "/org/freedesktop/DBus", + "org.freedesktop.DBus", "NameOwnerChanged", + iface_system_name_ownerchanged, NULL); + /* do an initial list */ + iface_system_interfaces_list(); + + /* FIXME: do we care about connman state? haven't found a use for it yet */ + /* FIXME: get state with GetState */ + /* FIXME: add signal handler StateChanged */ +} + +void +iface_system_shutdown(void) +{ + Evas_List *l, *tlist = NULL; + + for (l = interfaces; l; l = l->next) + tlist = evas_list_append(tlist, l->data); + while (tlist) + { + iface_unref(tlist->data); + tlist = evas_list_remove_list(tlist, tlist); + } + if (sigh_name_ownerchanged) + e_dbus_signal_handler_del(conn, sigh_name_ownerchanged); + sigh_name_ownerchanged = NULL; + if (sigh_interface_added) + e_dbus_signal_handler_del(conn, sigh_interface_added); + sigh_interface_added = NULL; + if (sigh_interface_removed) + e_dbus_signal_handler_del(conn, sigh_interface_removed); + sigh_interface_removed = NULL; + while (callbacks) + { + free(callbacks->data); + callbacks = evas_list_remove_list(callbacks, callbacks); + } + conn = NULL; +} + +void +iface_system_callback_add(Interface_Event event, void (*func) (void *data, Interface *iface, Interface_Network *ifnet), void *data) +{ + Interface_Callback *cb; + + cb = calloc(1, sizeof(Interface_Callback)); + if (!cb) return; + cb->event = event; + cb->func = func; + cb->data = data; + callbacks = evas_list_append(callbacks, cb); +} + +void +iface_system_callback_del(Interface_Event event, void (*func) (void *data, Interface *iface, Interface_Network *ifnet), void *data) +{ + Evas_List *l; + + for (l = callbacks; l; l = l->next) + { + Interface_Callback *cb; + + cb = l->data; + if ((cb->event == event) && (cb->func == func) && (cb->data == data)) + { + /* just flag for deletion - cleanup happens later */ + cb->delete_me = 1; + return; + } + } +} + + + + + + + + + +#if 0// TESTING CODE ONLY HERE - EXCERCISE THE API ABOVE +static void +cb_if_del(void *data, Interface *iface, Interface_Network *ifnet) +{ + printf("IF-- %s\n", iface->ifpath); +} + +static void +cb_if_ipv4(void *data, Interface *iface, Interface_Network *ifnet) +{ + printf("IF %s\n", iface->ifpath); + printf(" IPV4: [%s][%s][%s][%s]\n", + iface->ipv4.method, iface->ipv4.address, + iface->ipv4.gateway, iface->ipv4.netmask); +} + +static void +cb_if_net_sel(void *data, Interface *iface, Interface_Network *ifnet) +{ + printf("IF %s\n", iface->ifpath); + printf(" NET_SEL: [%s] [%s]\n", + iface->network_selection.id, iface->network_selection.pass); +} + +static void +cb_if_scan_net_add(void *data, Interface *iface, Interface_Network *ifnet) +{ + printf("IF %s\n", iface->ifpath); + printf(" SCAN NET ADD: [%s] %i \"%s\" %s\n", + ifnet->bssid, ifnet->signal_strength, ifnet->essid, ifnet->security); +} + +static void +cb_if_scan_net_del(void *data, Interface *iface, Interface_Network *ifnet) +{ + printf("IF %s\n", iface->ifpath); + printf(" SCAN NET DEL: [%s] %i \"%s\" %s\n", + ifnet->bssid, ifnet->signal_strength, ifnet->essid, ifnet->security); +} + +static void +cb_if_scan_net_change(void *data, Interface *iface, Interface_Network *ifnet) +{ + printf("IF %s\n", iface->ifpath); + printf(" SCAN NET CHANGE: [%s] %i \"%s\" %s\n", + ifnet->bssid, ifnet->signal_strength, ifnet->essid, ifnet->security); +} + +static void +cb_if_signal(void *data, Interface *iface, Interface_Network *ifnet) +{ + printf("IF %s\n", iface->ifpath); + printf(" SIGNAL: %i\n", iface->signal_strength); +} + +static int connect_test = 0; +static int disconnect_test = 0; +static double connect_timeout_test = 5.0; +static char *essid_test = ""; +static char *pass_test = ""; + +// this is testing - every 5 seconds connect then disconnect from the network +static int +delay_up(void *data) +{ + Interface *iface = data; + + // turn it back on + iface_policy_set(iface, "auto"); + iface_network_set(iface, essid_test, pass_test); + return 0; +} + +static int +delay_down(void *data) +{ + Interface *iface = data; + + // turn interface off + iface_policy_set(iface, "off"); + // in 5 seconds call delay_up + if (connect_test) + ecore_timer_add(connect_timeout_test, delay_up, iface); + return 0; +} + +static void +cb_if_state(void *data, Interface *iface, Interface_Network *ifnet) +{ + // .. iface->prop.state: + // scanning + // carrier + // configure + // ready + // unknown + // off + // enabled + // connect + // connected + printf("IF %s\n", iface->ifpath); + printf(" STATE: %s\n", iface->prop.state); + // if we go into a ready state - in 5 seconds, call delay_down + if (disconnect_test) + { + if (!strcmp(iface->prop.state, "ready")) + ecore_timer_add(connect_timeout_test, delay_down, iface); + } +} + +static void +cb_if_policy(void *data, Interface *iface, Interface_Network *ifnet) +{ + // .. iface->prop.policy: + // unknown + // off + // ignore + // auto + // ask + // + printf("IF %s\n", iface->ifpath); + printf(" POLICY: %s\n", iface->prop.policy); +} + +static void +cb_main_if_add(void *data, Interface *iface, Interface_Network *ifnet) +{ + printf("IF++ %s\n", iface->ifpath); + + // TESTING ... + // add callbacks to events so we know when things happen + iface_callback_add(iface, IFACE_EVENT_DEL, cb_if_del, NULL); + iface_callback_add(iface, IFACE_EVENT_IPV4_CHANGE, cb_if_ipv4, NULL); + iface_callback_add(iface, IFACE_EVENT_NETWORK_SELECTION_CHANGE, cb_if_net_sel, NULL); + iface_callback_add(iface, IFACE_EVENT_SCAN_NETWORK_ADD, cb_if_scan_net_add, NULL); + iface_callback_add(iface, IFACE_EVENT_SCAN_NETWORK_DEL, cb_if_scan_net_del, NULL); + iface_callback_add(iface, IFACE_EVENT_SCAN_NETWORK_CHANGE, cb_if_scan_net_change, NULL); + iface_callback_add(iface, IFACE_EVENT_SIGNAL_CHANGE, cb_if_signal, NULL); + iface_callback_add(iface, IFACE_EVENT_STATE_CHANGE, cb_if_state, NULL); + iface_callback_add(iface, IFACE_EVENT_POLICY_CHANGE, cb_if_policy, NULL); + + // .. iface->prop.type: + // unknown + // 80203 + // 80211 + // wimax + // modem + // bluetooth + // + // if it is 802.11 - try connect + if (essid_test) + { + if ((iface->prop.type) && (!strcmp(iface->prop.type, "80211"))) + { + iface_policy_set(iface, "auto"); + iface_network_set(iface, essid_test, pass_test); + } + } +} + +//////// DRIVE THE TESt SYSTEM ABOVE //////// +int +main(int argc, char **argv) +{ + E_DBus_Connection *c; + + { + int i; + + for (i = 0; i < argc; i++) + { + if (!strcmp(argv[i], "-ct")) + { + connect_test = 1; + } + else if (!strcmp(argv[i], "-dt")) + { + disconnect_test = 1; + } + else if (!strcmp(argv[i], "-e")) + { + essid_test = argv[++i]; + } + else if (!strcmp(argv[i], "-p")) + { + pass_test = argv[++i]; + } + else if (!strcmp(argv[i], "-t")) + { + connect_timeout_test = atof(argv[++i]); + } + else if (!strcmp(argv[i], "-h")) + { + printf + ("Options:\n" + " -ct Enable connection connect test\n" + " -dt Enable connection disconnect test\n" + " -t N Timeout for connect/disconnect test (seconds)\n" + " -e XXX Use Essid XXX\n" + " -p XXX Use passphrase XXX\n" + " -h This help\n" + ); + exit(0); + } + } + } + + ecore_init(); + ecore_string_init(); + ecore_app_args_set(argc, (const char **)argv); + e_dbus_init(); + evas_init(); + + c = e_dbus_bus_get(DBUS_BUS_SYSTEM); + if (!c) + { + printf("ERROR: can't connect to system session\n"); + exit(-1); + } + + // add calback that gets called whenever an interface is added to the system + // or on initial lst of interfaces that are present + iface_system_callback_add(IFACE_EVENT_ADD, cb_main_if_add, NULL); + iface_system_init(c); + + ecore_main_loop_begin(); + + iface_system_shutdown(); + + e_dbus_connection_close(c); + evas_shutdown(); + e_dbus_shutdown(); + ecore_string_shutdown(); + ecore_shutdown(); + + return 0; +} +#endif diff --git a/src/modules/connman/e_iface.h b/src/modules/connman/e_iface.h new file mode 100644 index 000000000..fc26eb116 --- /dev/null +++ b/src/modules/connman/e_iface.h @@ -0,0 +1,116 @@ +#ifndef E_IFACE_H +#define E_IFACE_H + +#include +#include +#include +#include +#include +#include +#include + +/* IFACE HEADER */ +typedef enum _Interface_Event +{ + IFACE_EVENT_ADD, + IFACE_EVENT_DEL, + IFACE_EVENT_IPV4_CHANGE, + IFACE_EVENT_NETWORK_SELECTION_CHANGE, + IFACE_EVENT_SCAN_NETWORK_ADD, + IFACE_EVENT_SCAN_NETWORK_DEL, + IFACE_EVENT_SCAN_NETWORK_CHANGE, + IFACE_EVENT_SIGNAL_CHANGE, + IFACE_EVENT_STATE_CHANGE, + IFACE_EVENT_POLICY_CHANGE, +} Interface_Event; + +typedef struct _Interface_Network Interface_Network; +typedef struct _Interface_Properties Interface_Properties; +typedef struct _Interface_IPv4 Interface_IPv4; +typedef struct _Interface_Network_Selection Interface_Network_Selection; +typedef struct _Interface_Callback Interface_Callback; +typedef struct _Interface Interface; + +struct _Interface_Network +{ + const char *essid; + const char *bssid; + const char *security; + int signal_strength; + double last_seen_time; +}; + +struct _Interface_Properties +{ + const char *product; + const char *vendor; + int signal_strength; + const char *driver; + const char *state; + const char *policy; + const char *type; +}; + +struct _Interface_IPv4 +{ + const char *method; + const char *address; + const char *gateway; + const char *netmask; +}; + +struct _Interface_Network_Selection +{ + const char *id; + const char *pass; +}; + +struct _Interface_Callback +{ + Interface_Event event; + void (*func) (void *data, Interface *iface, Interface_Network *ifnet); + void *data; + unsigned char delete_me : 1; +}; + +struct _Interface +{ + /* public - read-only. look but don't touch */ + const char *ifpath; + Interface_Properties prop; + Interface_IPv4 ipv4; + Interface_Network_Selection network_selection; + Evas_List *networks; + int signal_strength; + + /* private - don't touch */ + Evas_List *callbacks; + struct { + E_DBus_Signal_Handler *network_found; + E_DBus_Signal_Handler *signal_changed; + E_DBus_Signal_Handler *state_changed; + E_DBus_Signal_Handler *policy_changed; + E_DBus_Signal_Handler *network_changed; + E_DBus_Signal_Handler *ipv4_changed; + } sigh; + Ecore_Timer *network_timeout; + int ref; + unsigned char newif : 1; +}; + +/* IFACE PUBLIC API */ +Interface *iface_add (const char *ifpath); +void iface_ref (Interface *iface); +void iface_unref (Interface *iface); +Interface *iface_find (const char *ifpath); +void iface_network_set (Interface *iface, const char *ssid, const char *pass); +void iface_policy_set (Interface *iface, const char *policy); +void iface_scan (Interface *iface, const char *policy); +void iface_ipv4_set (Interface *iface, const char *method, const char *address, const char *gateway, const char *netmask); +void iface_callback_add(Interface *iface, Interface_Event event, void (*func) (void *data, Interface *iface, Interface_Network *ifnet), void *data); +void iface_callback_del(Interface *iface, Interface_Event event, void (*func) (void *data, Interface *iface, Interface_Network *ifnet), void *data); + +void iface_system_init (E_DBus_Connection *edbus_conn); +void iface_system_callback_add (Interface_Event event, void (*func) (void *data, Interface *iface, Interface_Network *ifnet), void *data); +void iface_system_callback_del (Interface_Event event, void (*func) (void *data, Interface *iface, Interface_Network *ifnet), void *data); +#endif diff --git a/src/modules/connman/e_mod_main.c b/src/modules/connman/e_mod_main.c new file mode 100644 index 000000000..f774f02d4 --- /dev/null +++ b/src/modules/connman/e_mod_main.c @@ -0,0 +1,1409 @@ +/* + * vim:ts=8:sw=3:sts=8:noexpandtab:cino=>5n-3f0^-2{2 + */ +#include "e.h" +#include "e_mod_main.h" +#include "e_iface.h" + +// FIXME: need config to +// 1. list instance id -> iface config +// 2. list networks (essid, password, dhcp?, ip, gw, netmask) + + +/***************************************************************************/ +/**/ +/* gadcon requirements */ +static E_Gadcon_Client *_gc_init(E_Gadcon *gc, const char *name, const char *id, const char *style); +static void _gc_shutdown(E_Gadcon_Client *gcc); +static void _gc_orient(E_Gadcon_Client *gcc); +static char *_gc_label(void); +static Evas_Object *_gc_icon(Evas *evas); +static const char *_gc_id_new(void); +/* and actually define the gadcon class that this module provides (just 1) */ +static const E_Gadcon_Client_Class _gadcon_class = +{ + GADCON_CLIENT_CLASS_VERSION, + "connman", + { + _gc_init, _gc_shutdown, _gc_orient, _gc_label, _gc_icon, _gc_id_new, NULL + }, + E_GADCON_CLIENT_STYLE_PLAIN +}; +/**/ +/***************************************************************************/ + +static void gadget_cb_mouse_down(void *data, Evas *evas, Evas_Object *obj, void *event); + +/***************************************************************************/ +/**/ +/* actual module specifics */ + +typedef struct _Instance Instance; +typedef struct _Conf Conf; +typedef struct _Conf_Interface Conf_Interface; +typedef struct _Conf_Network Conf_Network; + + +struct _Instance +{ + E_Gadcon_Client *gcc; + Evas_Object *o_net; // FIXME: clock to go... + + E_Gadcon_Popup *popup; + Evas_Object *popup_ilist_obj; + E_Dialog *if_dia; + Evas_Object *if_radio_device; + Evas_Object *if_ilist_obj; + E_Dialog *net_dia; + E_Dialog *manual_dia; + E_Dialog *netlist_dia; + + struct { + int ifmode; + char *ifpath; + char *bssid; + char *sec; + Conf_Network *cfnet, *cfnet_new; + } config; +}; + +struct _Conf_Interface +{ + const char *name; + const char *id; + const char *ifpath; + int ifmode; + Conf_Network *netconf; // if ethernet - then this will hold config +}; + +struct _Conf_Network +{ + char *name; + char *essid; + char *password; + char *ip; + char *gateway; + char *netmask; + int dhcp; + int remember_password; + int use_always; + int addme; +}; + +struct _Conf +{ + Evas_List *interfaces; + Evas_List *networks; +}; + +static E_Module *connman_module = NULL; +static E_DBus_Connection *connman_dbus = NULL; +static Evas_List *instances = NULL; +static E_Config_DD *conf_edd = NULL; +static E_Config_DD *conf_interface_edd = NULL; +static E_Config_DD *conf_network_edd = NULL; +static Conf *conf = NULL; + +static E_Gadcon_Client * +_gc_init(E_Gadcon *gc, const char *name, const char *id, const char *style) +{ + Evas_Object *o; + E_Gadcon_Client *gcc; + Instance *inst; + + inst = E_NEW(Instance, 1); + + o = edje_object_add(gc->evas); + e_theme_edje_object_set(o, "base/theme/modules/connman", + "e/modules/connman/main"); + evas_object_show(o); + + evas_object_event_callback_add(o, EVAS_CALLBACK_MOUSE_DOWN, + gadget_cb_mouse_down, inst); + + gcc = e_gadcon_client_new(gc, name, id, style, o); + gcc->data = inst; + + inst->gcc = gcc; + inst->o_net = o; + + e_gadcon_client_util_menu_attach(gcc); + + instances = evas_list_append(instances, inst); + + return gcc; +} + +static void +_gc_shutdown(E_Gadcon_Client *gcc) +{ + Instance *inst; + + inst = gcc->data; + instances = evas_list_remove(instances, inst); + + evas_object_del(inst->o_net); + free(inst); +} + +static void +_gc_orient(E_Gadcon_Client *gcc) +{ + Instance *inst; + Evas_Coord mw, mh; + + inst = gcc->data; + mw = 0, mh = 0; + edje_object_size_min_get(inst->o_net, &mw, &mh); + if ((mw < 1) || (mh < 1)) + edje_object_size_min_calc(inst->o_net, &mw, &mh); + if (mw < 4) mw = 4; + if (mh < 4) mh = 4; + e_gadcon_client_aspect_set(gcc, mw, mh); + e_gadcon_client_min_size_set(gcc, mw, mh); +} + +static char * +_gc_label(void) +{ + return _("Connection Manager"); +} + +static Evas_Object * +_gc_icon(Evas *evas) +{ + Evas_Object *o; + char buf[4096]; + + o = edje_object_add(evas); + snprintf(buf, sizeof(buf), "%s/e-module-connman.edj", + e_module_dir_get(connman_module)); + edje_object_file_set(o, buf, "icon"); + return o; +} + +static const char * +_gc_id_new(void) +{ + return _gadcon_class.name; +} + +/**/ +/***************************************************************************/ + +/***************************************************************************/ +/**/ +static void if_dialog_hide(Instance *inst); +static void popup_hide(Instance *inst); +static void net_dialog_hide(Instance *inst); +static void popup_ifnet_nets_refresh(Instance *inst); + +static Evas_List *ifaces = NULL; + +static int +inst_if_matches(Instance *inst, Interface *iface) +{ + if ((inst->config.ifmode == 0) && (iface->prop.type) && + (!strcmp(iface->prop.type, "80211"))) + return 1; + if ((inst->config.ifmode == 1) && (iface->prop.type) && + (!strcmp(iface->prop.type, "80203"))) + return 1; + if ((inst->config.ifpath) && (!strcmp(iface->ifpath, inst->config.ifpath))) + return 1; + return 0; +} + +static Interface * +if_get(Instance *inst) +{ + Evas_List *l; + Interface *iface = NULL; + + if (inst->config.ifpath) + iface = iface_find(inst->config.ifpath); + else + { + for (l = ifaces; l; l = l->next) + { + iface = l->data; + if (inst_if_matches(inst, iface)) return iface; + } + } + return iface; +} + +static int +net_join(Interface *iface, Conf_Network *cfnet, const char *sec) +{ + if (!sec) + { + iface_policy_set(iface, "auto"); + iface_network_set(iface, cfnet->essid, ""); + if (cfnet->dhcp) + { + iface_ipv4_set(iface, "dhcp", NULL, NULL, NULL); + } + else + iface_ipv4_set(iface, "static", + cfnet->ip, cfnet->gateway, + cfnet->netmask); + } + else + { + if (!cfnet->password) + { + // FIXME: ask for password + return 1; + } + else + { + iface_policy_set(iface, "auto"); + iface_network_set(iface, cfnet->essid, cfnet->password); + if (cfnet->dhcp) + { + iface_ipv4_set(iface, "dhcp", NULL, NULL, NULL); + } + else + iface_ipv4_set(iface, "static", + cfnet->ip, cfnet->gateway, + cfnet->netmask); + } + } + return 0; +} + +#define STR_SHARE(x) \ +do { char *___s; ___s = (x); \ + if (___s) { (x) = evas_stringshare_add(___s); free(___s); } \ +} while (0); + +#define STR_UNSHARE(x) \ +do { char *___s; ___s = (x); \ + if (___s) { (x) = strdup(___s); evas_stringshare_del(___s); } \ +} while (0); + + +static void +net_dialog_cb_ok(void *data, E_Dialog *dialog) +{ + Instance *inst; + Conf_Network *cfnet; + char *s; + Interface *iface; + + inst = data; + cfnet = inst->config.cfnet_new; + inst->config.cfnet = cfnet; + inst->config.cfnet_new = NULL; + if (cfnet->addme) + conf->networks = evas_list_prepend(conf->networks, cfnet); + STR_SHARE(cfnet->name); + STR_SHARE(cfnet->essid); + STR_SHARE(cfnet->password); + STR_SHARE(cfnet->ip); + STR_SHARE(cfnet->gateway); + STR_SHARE(cfnet->netmask); + net_dialog_hide(inst); + iface = if_get(inst); + if (iface) net_join(iface, cfnet, inst->config.sec); + // FIXME: save config - effect changed +} + +static void +net_dialog_cb_cancel(void *data, E_Dialog *dialog) +{ + Instance *inst; + Conf_Network *cfnet; + + inst = data; + cfnet = inst->config.cfnet_new; + inst->config.cfnet_new = NULL; + if (cfnet->addme) + { + E_FREE(cfnet->name); + E_FREE(cfnet->essid); + E_FREE(cfnet->password); + E_FREE(cfnet->ip); + E_FREE(cfnet->gateway); + E_FREE(cfnet->netmask); + free(cfnet); + } + net_dialog_hide(inst); +} + +static void +net_dialog_cb_del(E_Win *win) +{ + E_Dialog *dialog; + Instance *inst; + Conf_Network *cfnet; + + dialog = win->data; + inst = dialog->data; + cfnet = inst->config.cfnet_new; + inst->config.cfnet_new = NULL; + if (cfnet->addme) + { + E_FREE(cfnet->name); + E_FREE(cfnet->essid); + E_FREE(cfnet->password); + E_FREE(cfnet->ip); + E_FREE(cfnet->gateway); + E_FREE(cfnet->netmask); + free(cfnet); + } + net_dialog_hide(inst); +} + +// FIXME: need password dialog with: +// * entry "network name" (default ESSID if wifi) +// * checkbox "use this network whenever it is available" +// * checkbox "remember password for this network" // wifi only +// * entry "password" // wifi only +// * button for "address settings" // default dhcp +// +// if iface deleted - del dialog +// if ifnet del (this ifnet) del dialog +static void +net_dialog_show(Instance *inst, Conf_Network *cfnet) +{ + E_Dialog *dialog; + Evas *evas; + Evas_Object *table, *o, *button; + Evas_Coord mw, mh; + E_Radio_Group *rg; + Evas_List *l; + int row = 0; + + dialog = e_dialog_new(inst->gcc->gadcon->zone->container, "e", "e_connman_net_dialog"); + e_dialog_title_set(dialog, "Connection Details"); + dialog->data = inst; + evas = e_win_evas_get(dialog->win); + + table = e_widget_table_add(evas, 0); + + o = e_widget_label_add(evas, "Personal Name"); + e_widget_table_object_append(table, o, 0, row, 1, 1, 1, 1, 0, 0); + o = e_widget_entry_add(evas, &(cfnet->name), NULL, NULL, NULL); + e_widget_min_size_get(o, &mw, &mh); + mw = 160; + e_widget_min_size_set(o, mw, mh); + e_widget_table_object_append(table, o, 1, row, 1, 1, 1, 1, 0, 0); + row++; + + o = e_widget_label_add(evas, "ESSID"); + e_widget_table_object_append(table, o, 0, row, 1, 1, 1, 1, 0, 0); + o = e_widget_label_add(evas, cfnet->essid); + e_widget_table_object_append(table, o, 1, row, 1, 1, 1, 1, 0, 0); + row++; + + o = e_widget_check_add(evas, "Use when available", &(cfnet->use_always)); + e_widget_table_object_append(table, o, 0, row, 2, 1, 1, 1, 0, 0); + row++; + + if (inst->config.sec) + { + o = e_widget_label_add(evas, "Password"); + e_widget_table_object_append(table, o, 0, row, 1, 1, 1, 1, 0, 0); + o = e_widget_entry_add(evas, &(cfnet->password), NULL, NULL, NULL); + e_widget_min_size_get(o, &mw, &mh); + mw = 160; + e_widget_min_size_set(o, mw, mh); + e_widget_table_object_append(table, o, 1, row, 1, 1, 1, 1, 0, 0); + row++; + + o = e_widget_check_add(evas, "Remember password", &(cfnet->remember_password)); + e_widget_table_object_append(table, o, 0, row, 2, 1, 1, 1, 0, 0); + row++; + } + + button = e_widget_button_add(evas, "Address Details", NULL, NULL, + inst, NULL); + e_widget_table_object_append(table, button, 0, row, 2, 1, 0, 0, 0, 0); + row++; + + e_widget_min_size_get(table, &mw, &mh); + e_dialog_content_set(dialog, table, mw, mh); + + e_win_delete_callback_set(dialog->win, net_dialog_cb_del); + + e_dialog_button_add(dialog, "OK", NULL, net_dialog_cb_ok, inst); + e_dialog_button_add(dialog, "Cancel", NULL, net_dialog_cb_cancel, inst); + e_dialog_button_focus_num(dialog, 1); + e_win_centered_set(dialog->win, 1); + e_dialog_show(dialog); + + inst->net_dia = dialog; +} + +static void +net_dialog_hide(Instance *inst) +{ + if (inst->net_dia) + { + e_object_del(E_OBJECT(inst->net_dia)); + inst->net_dia = NULL; + } +} + +// FIXME: need a "manual network settings" dialog: +// * checkbox "use dhcp" +// * entry "ip" +// * entry "gateway" +// * entry "netmask" +// +// if net_dialog del - del dialog +static void +manual_dialog_show(Instance *inst) +{ +} + +static void +manual_dialog_hide(Instance *inst) +{ +} + +// FIXME: need saved networks list dialog +// * ilist of saved network names +// * delete button +// +// if saved networks list add/del, refill list +// if if_dialog parent del, del dialog +static void +netlist_dialog_show(Instance *inst) +{ +} + +static void +netlist_dialog_hide(Instance *inst) +{ +} + +static void +button_cb_netlist(void *data, void *data2) +{ + Instance *inst; + + inst = data; + if (!inst->netlist_dia) netlist_dialog_show(inst); + else netlist_dialog_hide(inst); +} + +static void +if_dialog_cb_ok(void *data, E_Dialog *dialog) +{ + Instance *inst; + + inst = data; + if_dialog_hide(inst); + // FIXME: save config - effect changed +} + +static void +if_dialog_cb_del(E_Win *win) +{ + E_Dialog *dialog; + Instance *inst; + + dialog = win->data; + inst = dialog->data; + if_dialog_hide(inst); + // FIXME: save config - effect changed +} + +static void +if_radio_cb_generic(void *data, Evas_Object *obj, void *event_info) +{ + Instance *inst; + + inst = data; + if (inst->config.ifmode != 2) + { + e_widget_ilist_unselect(inst->if_ilist_obj); + E_FREE(inst->config.ifpath); + } + popup_ifnet_nets_refresh(inst); +} + +static void +if_ilist_cb_if_sel(void *data) +{ + Instance *inst; + + inst = data; + e_widget_radio_toggle_set(inst->if_radio_device, 1); + popup_ifnet_nets_refresh(inst); +} + +static void +if_ilist_update(Instance *inst) +{ + Evas_Object *ilist; + Evas_List *l; + int i; + + ilist = inst->if_ilist_obj; + if (!ilist) return; + e_widget_ilist_freeze(ilist); + e_widget_ilist_clear(ilist); + + for (i = 0, l = ifaces; l; l = l->next, i++) + { + Interface *iface; + char buf[256]; + const char *vendor, *product, *type; + Evas_Object *icon; + + iface = l->data; + vendor = iface->prop.vendor; + product = iface->prop.product; + type = iface->prop.type; + icon = NULL; + if (type) + { + if (!strcmp(type, "80211")) + { + type = "WiFi"; + // FIXME: find an icon; + } + else if (!strcmp(type, "80203")) + { + type = "LAN"; + // FIXME: find an icon; + } + else if (!strcmp(type, "wimax")) + { + type = "WiMax"; + // FIXME: find an icon; + } + else if (!strcmp(type, "modem")) + { + type = "Modem"; + // FIXME: find an icon; + } + else if (!strcmp(type, "bluetooth")) + { + type = "Bluetooth"; + // FIXME: find an icon; + } + } + if (!vendor) vendor = "Unknown"; + if (!product) product = "Unknown"; + if (!type) type = "Unknown"; + snprintf(buf, sizeof(buf), "%s (%s)", type, product); + e_widget_ilist_append(ilist, icon, buf, if_ilist_cb_if_sel, inst, + iface->ifpath); + if ((inst->config.ifpath) && + (!strcmp(inst->config.ifpath, iface->ifpath))) + e_widget_ilist_selected_set(ilist, i); + } + + e_widget_ilist_go(ilist); + e_widget_ilist_thaw(ilist); +} + +static void +if_dialog_show(Instance *inst) +{ + E_Dialog *dialog; + Evas *evas; + Evas_Object *list, *flist, *o, *ilist, *button; + Evas_Coord mw, mh; + E_Radio_Group *rg; + Evas_List *l; + + dialog = e_dialog_new(inst->gcc->gadcon->zone->container, "e", "e_connman_iface_dialog"); + e_dialog_title_set(dialog, "Network Connection Settings"); + dialog->data = inst; + evas = e_win_evas_get(dialog->win); + + list = e_widget_list_add(evas, 0, 0); + + flist = e_widget_framelist_add(evas, "Network Device", 0); + + rg = e_widget_radio_group_new(&(inst->config.ifmode)); + + o = e_widget_radio_add(evas, "Wifi", 0, rg); + evas_object_smart_callback_add(o, "changed", if_radio_cb_generic, inst); + e_widget_framelist_object_append(flist, o); + o = e_widget_radio_add(evas, "LAN", 1, rg); + evas_object_smart_callback_add(o, "changed", if_radio_cb_generic, inst); + e_widget_framelist_object_append(flist, o); + o = e_widget_radio_add(evas, "Specific Device", 2, rg); + inst->if_radio_device = o; + e_widget_framelist_object_append(flist, o); + + ilist = e_widget_ilist_add(evas, 48, 48, &(inst->config.ifpath)); + inst->if_ilist_obj = ilist; + + e_widget_ilist_freeze(ilist); + + if_ilist_update(inst); + + e_widget_ilist_go(ilist); + e_widget_ilist_thaw(ilist); + + e_widget_min_size_set(ilist, 240, 180); + e_widget_framelist_object_append(flist, ilist); + + e_widget_list_object_append(list, flist, 1, 0, 0.5); + + button = e_widget_button_add(evas, "Networks", NULL, button_cb_netlist, + inst, NULL); + e_widget_list_object_append(list, button, 1, 0, 0.5); + + e_widget_min_size_get(list, &mw, &mh); + e_dialog_content_set(dialog, list, mw, mh); + + e_win_delete_callback_set(dialog->win, if_dialog_cb_del); + + e_dialog_button_add(dialog, "OK", NULL, if_dialog_cb_ok, inst); + e_dialog_button_focus_num(dialog, 1); + e_win_centered_set(dialog->win, 1); + e_dialog_show(dialog); + + inst->if_dia = dialog; +} + +static void +if_dialog_hide(Instance *inst) +{ + if (inst->if_dia) + { + e_object_del(E_OBJECT(inst->if_dia)); + inst->if_dia = NULL; + inst->if_radio_device = NULL; + inst->if_ilist_obj = NULL; + } +} + + + + + +static void +popup_cb_setup(void *data, void *data2) +{ + Instance *inst; + + inst = data; + if (!inst->if_dia) if_dialog_show(inst); + else if_dialog_hide(inst); +} + +static void +popup_cb_resize(Evas_Object *obj, int *w, int *h) +{ + int mw, mh; + + e_widget_min_size_get(obj, &mw, &mh); + + if (mh < 180) mh = 180; + if (mw < 160) mw = 160; + + if (*w) *w = (mw + 8); + if (*h) *h = (mh + 8); +} + +static void +popup_ifnet_icon_adjust(Evas_Object *icon, Interface_Network *ifnet) +{ + Edje_Message_Int_Set *msg; + + msg = alloca(sizeof(Edje_Message_Int_Set) + (0 * sizeof(int))); + msg->count = 1; + msg->val[0] = ifnet->signal_strength; + edje_object_message_send(icon, EDJE_MESSAGE_INT_SET, 1, msg); + + if (ifnet->security) + { + if (!strcmp(ifnet->security, "WEP")) + edje_object_signal_emit(icon, "s,state,security,wep", "e"); + else if (!strcmp(ifnet->security, "WPA")) + edje_object_signal_emit(icon, "s,state,security,wpa", "e"); + else if (!strcmp(ifnet->security, "RSN")) + edje_object_signal_emit(icon, "s,state,security,rsn", "e"); + } + else + edje_object_signal_emit(icon, "s,state,security,open", "e"); + + // FIXME: adjust saved network state +} + +static void +popup_cb_ifnet_sel(void *data) +{ + Instance *inst; + Evas_List *l; + Interface *iface; + + inst = data; + if (!inst->config.bssid) return; + iface = if_get(inst); + if (!iface) return; + for (l = iface->networks; l; l = l->next) + { + Interface_Network *ifnet; + + ifnet = l->data; + E_FREE(inst->config.sec); + if (ifnet->security) inst->config.sec = strdup(ifnet->security); + if (!strcmp(inst->config.bssid, ifnet->bssid)) + { + Conf_Network *cfnet; + char buf[256]; + + printf("SEL %s\n", ifnet->essid); + if (!conf) + conf = E_NEW(Conf, 1); + for (l = conf->networks; l; l = l->next) + { + cfnet = l->data; + if (!strcmp(cfnet->essid, ifnet->essid)) + { + STR_UNSHARE(cfnet->name); + STR_UNSHARE(cfnet->essid); + STR_UNSHARE(cfnet->password); + STR_UNSHARE(cfnet->ip); + STR_UNSHARE(cfnet->gateway); + STR_UNSHARE(cfnet->netmask); + inst->config.cfnet_new = cfnet; + net_dialog_show(inst, cfnet); + popup_hide(inst); + return; + } + } + cfnet = E_NEW(Conf_Network, 1); + conf->networks = evas_list_prepend(conf->networks, cfnet); + if (ifnet->essid) + { + snprintf(buf, sizeof(buf), ifnet->essid); + cfnet->name = strdup(buf); + cfnet->essid = strdup(ifnet->essid); + } + else + cfnet->name = strdup("NONE"); + cfnet->remember_password = 1; + cfnet->dhcp = 1; + cfnet->addme = 1; + inst->config.cfnet_new = cfnet; + net_dialog_show(inst, cfnet); + popup_hide(inst); + return; + } + } + popup_hide(inst); +} + +static void +popup_ifnet_net_add(Instance *inst, Interface_Network *ifnet) +{ + const char *label; + Evas_Object *icon; + + label = ifnet->essid; + if (!label) label = "NONE"; + icon = edje_object_add(evas_object_evas_get(inst->popup_ilist_obj)); + e_theme_edje_object_set(icon, "base/theme/modules/connman", + "e/modules/connman/network"); + popup_ifnet_icon_adjust(icon, ifnet); + e_widget_ilist_append(inst->popup_ilist_obj, icon, label, + popup_cb_ifnet_sel, inst, ifnet->bssid); + evas_object_show(icon); +} + +static int +popup_ifnet_cb_sort(void *data1, void *data2) +{ + Interface_Network *ifnet1, *ifnet2; + + ifnet1 = data1; + ifnet2 = data2; + return ifnet2->signal_strength - ifnet1->signal_strength; +} + +static void +popup_ifnet_nets_refresh(Instance *inst) +{ + Evas_List *l, *networks = NULL; + Interface *iface; + Evas_Object *ilist; + Evas_List *nets; + + if (!inst->popup_ilist_obj) return; + ilist = inst->popup_ilist_obj; + + iface = if_get(inst); + + e_widget_ilist_freeze(ilist); + e_widget_ilist_clear(ilist); + + if (iface) + { + for (l = iface->networks; l; l = l->next) + networks = evas_list_append(networks, l->data); + } +// if (networks) +// networks = evas_list_sort(networks, +// evas_list_count(networks), +// popup_ifnet_cb_sort); + + for (l = networks; l; l = l->next) + { + Interface_Network *ifnet; + + ifnet = l->data; + popup_ifnet_net_add(inst, ifnet); + } + if (networks) evas_list_free(networks); + + e_widget_ilist_go(ilist); + e_widget_ilist_thaw(ilist); +} + +static int +ifnet_num_get(Interface *iface, Interface_Network *ifnet) +{ + Evas_List *l; + int i; + + for (i = 0, l = iface->networks; l; l = l->next, i++) + { + if (ifnet == l->data) return i; + } + return -1; +} + +static void +popup_ifnet_add(Instance *inst, Interface *iface, Interface_Network *ifnet) +{ + if (!inst->popup_ilist_obj) return; + popup_ifnet_net_add(inst, ifnet); + e_widget_ilist_go(inst->popup_ilist_obj); +// popup_ifnet_nets_refresh(inst); +} + +static void +popup_ifnet_del(Instance *inst, Interface *iface, Interface_Network *ifnet) +{ + int i; + + if (!inst->popup_ilist_obj) return; + i = ifnet_num_get(iface, ifnet); + if (i < 0) return; + e_widget_ilist_remove_num(inst->popup_ilist_obj, i); + e_widget_ilist_go(inst->popup_ilist_obj); +// popup_ifnet_nets_refresh(inst); +} + +static void +popup_ifnet_change(Instance *inst, Interface *iface, Interface_Network *ifnet) +{ + const char *label; + Evas_Object *icon; + int i; + + if (!inst->popup_ilist_obj) return; + i = ifnet_num_get(iface, ifnet); + if (i < 0) return; + icon = e_widget_ilist_nth_icon_get(inst->popup_ilist_obj, i); + if (icon) popup_ifnet_icon_adjust(icon, ifnet); + label = ifnet->essid; + if (!label) label = "NONE"; + e_widget_ilist_nth_label_set(inst->popup_ilist_obj, i, label); +// popup_ifnet_nets_refresh(inst); +} + +static void +popup_show(Instance *inst) +{ + Evas_Object *base, *ilist, *button; + Evas *evas; + + inst->popup = e_gadcon_popup_new(inst->gcc, popup_cb_resize); + evas = inst->popup->win->evas; + + edje_freeze(); + + base = e_widget_table_add(evas, 0); + + // FIXME: if iface set and this is wifi - then list, otherwise none + // FIXME: 96, 48 - get from min size from edje for icon... + ilist = e_widget_ilist_add(evas, 96, 48, &(inst->config.bssid)); + inst->popup_ilist_obj = ilist; + + e_widget_ilist_freeze(ilist); + + popup_ifnet_nets_refresh(inst); + + e_widget_ilist_go(ilist); + e_widget_ilist_thaw(ilist); + + e_widget_min_size_set(ilist, 240, 320); + e_widget_table_object_append(base, ilist, + 0, 0, 1, 1, 1, 1, 1, 1); + + button = e_widget_button_add(evas, "Settings", NULL, popup_cb_setup, + inst, NULL); + e_widget_table_object_append(base, button, + 0, 1, 1, 1, 0, 0, 0, 0); + + edje_thaw(); + + e_gadcon_popup_content_set(inst->popup, base); + e_gadcon_popup_show(inst->popup); +} + +static void +popup_hide(Instance *inst) +{ + if (inst->popup) + { + e_object_del(E_OBJECT(inst->popup)); + inst->popup = NULL; + inst->popup_ilist_obj = NULL; + } +} + +static void +gadget_cb_mouse_down(void *data, Evas *evas, Evas_Object *obj, void *event) +{ + Instance *inst; + Evas_Event_Mouse_Down *ev; + + ev = event; + inst = data; + if (ev->button == 1) + { + if (!inst->popup) popup_show(inst); + else popup_hide(inst); + } +} + +static void +inst_enable(Instance *inst) +{ + // FIXME: emit signal to enable +} + +static void +inst_disable(Instance *inst) +{ + // FIXME: emit signal to disable +} + +static void +inst_type(Instance *inst, const char *type) +{ + // FIXME: emit signal to change type +} + +static void +inst_connected(Instance *inst) +{ + // FIXME: emit signal +} + +static void +inst_disconnected(Instance *inst) +{ + // FIXME: emit signal +} + +static void +inst_connecting(Instance *inst) +{ + // FIXME: emit signal +} + +static void +inst_associating(Instance *inst) +{ + // FIXME: emit signal +} + +static void +inst_associated(Instance *inst) +{ + // FIXME: emit signal +} + +static void +inst_signal(Instance *inst, int sig) +{ + // FIXME: emit signal +} + +static void +inst_unknown(Instance *inst) +{ + // FIXME: emit signal +} + +static void +inst_off(Instance *inst) +{ + // FIXME: emit signal +} + +static void +inst_on(Instance *inst) +{ + // FIXME: emit signal +} + +static void +cb_if_del(void *data, Interface *iface, Interface_Network *ifnet) +{ + Evas_List *l; + + printf("IF-- %s\n", iface->ifpath); + ifaces = evas_list_remove(ifaces, iface); + // FIXME: any instances for this iface - set to disabled + for (l = instances; l; l = l->next) + { + Instance *inst; + + inst = l->data; + if (inst_if_matches(inst, iface)) + inst_disable(inst); + if_ilist_update(inst); + } +} + +static void +cb_if_ipv4(void *data, Interface *iface, Interface_Network *ifnet) +{ + Evas_List *l; + + printf("IF %s\n", iface->ifpath); + printf(" IPV4: [%s][%s][%s][%s]\n", + iface->ipv4.method, iface->ipv4.address, + iface->ipv4.gateway, iface->ipv4.netmask); + // FIXME: change status to say we connected fully now + for (l = instances; l; l = l->next) + { + Instance *inst; + + inst = l->data; + if (inst_if_matches(inst, iface)) + inst_connected(inst); + } +} + +static void +cb_if_net_sel(void *data, Interface *iface, Interface_Network *ifnet) +{ + Evas_List *l; + + printf("IF %s\n", iface->ifpath); + printf(" NET_SEL: [%s] [%s]\n", + iface->network_selection.id, iface->network_selection.pass); + // FIXME: change status to say we managed to select a network + for (l = instances; l; l = l->next) + { + Instance *inst; + + inst = l->data; + if (inst_if_matches(inst, iface)) + inst_associating(inst); + } +} + +static void +cb_if_scan_net_add(void *data, Interface *iface, Interface_Network *ifnet) +{ + Evas_List *l; + +// printf("IF %s\n", iface->ifpath); +// printf(" SCAN NET ADD: [%s] %i \"%s\" %s\n", +// ifnet->bssid, ifnet->signal_strength, ifnet->essid, ifnet->security); + // FIXME: if net strenght > current strength AND + // if scan has essid we have config for: + // iface_network_set(iface, "essid", "pass"); + // iface_ipv4_set(iface, "dhcp", NULL, NULL, NULL); + for (l = instances; l; l = l->next) + { + Instance *inst; + + inst = l->data; + if (inst_if_matches(inst, iface)) + popup_ifnet_add(l->data, iface, ifnet); + } +} + +static void +cb_if_scan_net_del(void *data, Interface *iface, Interface_Network *ifnet) +{ + Evas_List *l; + +// printf("IF %s\n", iface->ifpath); +// printf(" SCAN NET DEL: [%s] %i \"%s\" %s\n", +// ifnet->bssid, ifnet->signal_strength, ifnet->essid, ifnet->security); + // FIXME: walk networks - if any are in config, add to list, find strongest + // for the stringest one: + // iface_network_set(iface, "essid", "pass"); + // iface_ipv4_set(iface, "dhcp", NULL, NULL, NULL); + for (l = instances; l; l = l->next) + { + Instance *inst; + + inst = l->data; + if (inst_if_matches(inst, iface)) + popup_ifnet_del(l->data, iface, ifnet); + } +} + +static void +cb_if_scan_net_change(void *data, Interface *iface, Interface_Network *ifnet) +{ + Evas_List *l; + +// printf("IF %s\n", iface->ifpath); +// printf(" SCAN NET CHANGE: [%s] %i \"%s\" %s\n", +// ifnet->bssid, ifnet->signal_strength, ifnet->essid, ifnet->security); + for (l = instances; l; l = l->next) + { + Instance *inst; + + inst = l->data; + if (inst_if_matches(inst, iface)) + popup_ifnet_change(l->data, iface, ifnet); + } +} + +static void +cb_if_signal(void *data, Interface *iface, Interface_Network *ifnet) +{ + Evas_List *l; + + printf("IF %s\n", iface->ifpath); + printf(" SIGNAL: %i\n", iface->signal_strength); + for (l = instances; l; l = l->next) + { + Instance *inst; + + inst = l->data; + if (inst_if_matches(inst, iface)) + inst_signal(inst, iface->signal_strength); + } +} + +static void +cb_if_state(void *data, Interface *iface, Interface_Network *ifnet) +{ + Evas_List *l; + + // .. iface->prop.state: + // scanning + // carrier + // configure + // ready + // unknown + // off + // enabled + // connect + // connected + printf("IF %s\n", iface->ifpath); + printf(" STATE: %s\n", iface->prop.state); + // FIXME: show state instnaces for this iface + for (l = instances; l; l = l->next) + { + Instance *inst; + + inst = l->data; + if (inst_if_matches(inst, iface)) + { + if (!strcmp(iface->prop.state, "unknown")) + inst_disconnected(inst); + else if (!strcmp(iface->prop.state, "off")) + inst_disconnected(inst); + else if (!strcmp(iface->prop.state, "carrier")) + inst_connecting(inst); + else if (!strcmp(iface->prop.state, "configure")) + inst_associated(inst); + else if (!strcmp(iface->prop.state, "ready")) + inst_connected(inst); + else if (!strcmp(iface->prop.state, "enabled")) + inst_associating(inst); + else if (!strcmp(iface->prop.state, "connect")) + inst_connecting(inst); + else if (!strcmp(iface->prop.state, "connected")) + inst_connected(inst); + } + } +} + +static void +cb_if_policy(void *data, Interface *iface, Interface_Network *ifnet) +{ + Evas_List *l; + + // .. iface->prop.policy: + // unknown + // off + // ignore + // auto + // ask + // + printf("IF %s\n", iface->ifpath); + printf(" POLICY: %s\n", iface->prop.policy); + for (l = instances; l; l = l->next) + { + Instance *inst; + + inst = l->data; + if (inst_if_matches(inst, iface)) + { + if (!strcmp(iface->prop.policy, "unknown")) + inst_unknown(inst); + else if (!strcmp(iface->prop.policy, "off")) + inst_off(inst); + else if (!strcmp(iface->prop.policy, "ignore")) + inst_off(inst); + else if (!strcmp(iface->prop.policy, "auto")) + inst_on(inst); + else if (!strcmp(iface->prop.policy, "ask")) + inst_on(inst); + } + } +} + +static void +cb_main_if_add(void *data, Interface *iface, Interface_Network *ifnet) +{ + Evas_List *l; + + printf("IF++ %s\n", iface->ifpath); + ifaces = evas_list_append(ifaces, iface); + iface_callback_add(iface, IFACE_EVENT_DEL, cb_if_del, NULL); + iface_callback_add(iface, IFACE_EVENT_IPV4_CHANGE, cb_if_ipv4, NULL); + iface_callback_add(iface, IFACE_EVENT_NETWORK_SELECTION_CHANGE, cb_if_net_sel, NULL); + iface_callback_add(iface, IFACE_EVENT_SCAN_NETWORK_ADD, cb_if_scan_net_add, NULL); + iface_callback_add(iface, IFACE_EVENT_SCAN_NETWORK_DEL, cb_if_scan_net_del, NULL); + iface_callback_add(iface, IFACE_EVENT_SCAN_NETWORK_CHANGE, cb_if_scan_net_change, NULL); + iface_callback_add(iface, IFACE_EVENT_SIGNAL_CHANGE, cb_if_signal, NULL); + iface_callback_add(iface, IFACE_EVENT_STATE_CHANGE, cb_if_state, NULL); + iface_callback_add(iface, IFACE_EVENT_POLICY_CHANGE, cb_if_policy, NULL); + + for (l = instances; l; l = l->next) + { + Instance *inst; + + inst = l->data; + if (inst_if_matches(inst, iface)) + { + inst_enable(inst); + if (!strcmp(iface->prop.policy, "unknown")) + inst_unknown(inst); + else if (!strcmp(iface->prop.policy, "off")) + inst_off(inst); + else if (!strcmp(iface->prop.policy, "ignore")) + inst_off(inst); + else if (!strcmp(iface->prop.policy, "auto")) + inst_on(inst); + else if (!strcmp(iface->prop.policy, "ask")) + inst_on(inst); + + // FIXME: if iface has manual config then: + // iface_policy_set(iface, "ask"); + // if (80211) iface_network_set(iface, "essid", "pass"); + // iface_ipv4_set(iface, "static", "ip", "gw", "mask"); + // + // FIXME: if no manual setup: + // iface_policy_set(iface, "auto"); + // iface_scan(iface); + } + if_ilist_update(l->data); + } +} + +/**/ +/***************************************************************************/ + +/***************************************************************************/ +/**/ +/* module setup */ +EAPI E_Module_Api e_modapi = +{ + E_MODULE_API_VERSION, + "Connection Manager" +}; + +EAPI void * +e_modapi_init(E_Module *m) +{ + connman_module = m; + + conf_network_edd = E_CONFIG_DD_NEW("Conf_Network", Conf_Network); + E_CONFIG_VAL(conf_network_edd, Conf_Network, name, STR); + E_CONFIG_VAL(conf_network_edd, Conf_Network, essid, STR); + E_CONFIG_VAL(conf_network_edd, Conf_Network, password, STR); + E_CONFIG_VAL(conf_network_edd, Conf_Network, ip, STR); + E_CONFIG_VAL(conf_network_edd, Conf_Network, gateway, STR); + E_CONFIG_VAL(conf_network_edd, Conf_Network, netmask, STR); + E_CONFIG_VAL(conf_network_edd, Conf_Network, dhcp, INT); + E_CONFIG_VAL(conf_network_edd, Conf_Network, remember_password, INT); + E_CONFIG_VAL(conf_network_edd, Conf_Network, use_always, INT); + + conf_interface_edd = E_CONFIG_DD_NEW("Conf_Interface", Conf_Interface); + E_CONFIG_VAL(conf_interface_edd, Conf_Interface, name, STR); + E_CONFIG_VAL(conf_interface_edd, Conf_Interface, id, STR); + E_CONFIG_VAL(conf_interface_edd, Conf_Interface, ifpath, STR); + E_CONFIG_VAL(conf_interface_edd, Conf_Interface, ifmode, INT); + E_CONFIG_SUB(conf_interface_edd, Conf_Interface, netconf, conf_network_edd); + + conf_edd = E_CONFIG_DD_NEW("Conf", Conf); + E_CONFIG_LIST(conf_edd, Conf, interfaces, conf_interface_edd); + E_CONFIG_LIST(conf_edd, Conf, networks, conf_network_edd); + + conf = e_config_domain_load("module.connman", conf_edd); + + connman_dbus = e_dbus_bus_get(DBUS_BUS_SYSTEM); + if (connman_dbus) + { + iface_system_callback_add(IFACE_EVENT_ADD, cb_main_if_add, NULL); + iface_system_init(connman_dbus); + } + + e_gadcon_provider_register(&_gadcon_class); + return m; +} + +EAPI int +e_modapi_shutdown(E_Module *m) +{ + connman_module = NULL; + + // FIXME: free conf + + E_CONFIG_DD_FREE(conf_network_edd); + E_CONFIG_DD_FREE(conf_interface_edd); + E_CONFIG_DD_FREE(conf_edd); + + conf_network_edd = NULL; + conf_interface_edd = NULL; + conf_edd = NULL; + + e_gadcon_provider_unregister(&_gadcon_class); + if (connman_dbus) + { + if (ifaces) + { + evas_list_free(ifaces); + ifaces = NULL; + } + iface_system_shutdown(); + e_dbus_connection_close(connman_dbus); + connman_dbus = NULL; + } + + return 1; +} + +EAPI int +e_modapi_save(E_Module *m) +{ + return 1; +} diff --git a/src/modules/connman/e_mod_main.h b/src/modules/connman/e_mod_main.h new file mode 100644 index 000000000..2eb60362e --- /dev/null +++ b/src/modules/connman/e_mod_main.h @@ -0,0 +1,13 @@ +/* + * vim:ts=8:sw=3:sts=8:noexpandtab:cino=>5n-3f0^-2{2 + */ +#ifndef E_MOD_MAIN_H +#define E_MOD_MAIN_H + +EAPI extern E_Module_Api e_modapi; + +EAPI void *e_modapi_init (E_Module *m); +EAPI int e_modapi_shutdown (E_Module *m); +EAPI int e_modapi_save (E_Module *m); + +#endif diff --git a/src/modules/connman/module.desktop.in b/src/modules/connman/module.desktop.in new file mode 100644 index 000000000..c6e9abaa4 --- /dev/null +++ b/src/modules/connman/module.desktop.in @@ -0,0 +1,6 @@ +[Desktop Entry] +Type=Link +Name=Connection Manager +Icon=e-module-connman +Comment=Network Connection Manager Gadget

Control Wifi and wired networks as a user. +X-Enlightenment-ModuleType=system diff --git a/src/modules/mixer/e_mod_main.c b/src/modules/mixer/e_mod_main.c index cc29e8adc..232aebf54 100644 --- a/src/modules/mixer/e_mod_main.c +++ b/src/modules/mixer/e_mod_main.c @@ -174,14 +174,14 @@ _mixer_gadget_update(E_Mixer_Instance *inst) e_mixer_system_get_state(inst->sys, inst->channel, &inst->mixer_state); - msg = alloca(sizeof(Edje_Message_Int_Set) + 2 * sizeof(int)); + msg = alloca(sizeof(Edje_Message_Int_Set) + (2 * sizeof(int))); msg->count = 3; msg->val[0] = inst->mixer_state.mute; msg->val[1] = inst->mixer_state.left; msg->val[2] = inst->mixer_state.right; edje_object_message_send(inst->ui.gadget, EDJE_MESSAGE_INT_SET, 0, msg); - edje_object_signal_emit(inst->ui.gadget, "e,action,volume,change", ""); + edje_object_signal_emit(inst->ui.gadget, "e,action,volume,change", "e"); if (inst->popup) _mixer_popup_update(inst);