[enable_ehal=$enableval],
[enable_ehal="yes"])
AC_ARG_ENABLE(enm,
- AC_HELP_STRING([--disable-enm],
+ AC_HELP_STRING([--disable-enm],
[Disable enm build]),
[enable_enm=$enableval],
[enable_enm="yes"])
AC_ARG_ENABLE(enotify,
- AC_HELP_STRING([--disable-enotify],
+ AC_HELP_STRING([--disable-enotify],
[Disable enotify build]),
[enable_enotify=$enableval],
[enable_enotify="yes"])
+AC_ARG_ENABLE(econnman,
+ AC_HELP_STRING([--disable-econnman],
+ [Disable econnman build]),
+ [enable_econnman=$enableval],
+ [enable_econnman="yes"])
PKG_CHECK_MODULES([EINA], [eina-0])
AM_CONDITIONAL([BUILD_EHAL], [test "x${enable_ehal}" = "xyes"])
AM_CONDITIONAL([BUILD_ENM], [test "x${enable_enm}" = "xyes"])
AM_CONDITIONAL([BUILD_ENOTIFY], [test "x${enable_enotify}" = "xyes"])
+AM_CONDITIONAL([BUILD_ECONNMAN], [test "x${enable_econnman}" = "xyes"])
AC_OUTPUT([
e_dbus.spec
src/lib/hal/Makefile
src/lib/nm/Makefile
src/lib/notification/Makefile
+src/lib/connman/Makefile
src/bin/Makefile
edbus.pc
ehal.pc
enotify.pc
enm.pc
+econnman.pc
])
echo " EHal.................: $enable_ehal"
echo " ENM..................: $enable_enm"
echo " ENotify..............: $enable_enotify"
+echo " EConnman.............: $enable_econnman"
echo
echo "Configuration Options Summary:"
echo
--- /dev/null
+prefix=@prefix@
+exec_prefix=@exec_prefix@
+libdir=@libdir@
+includedir=@includedir@
+
+Name: econnman
+Description: network connection manager (connman)
+Requires: ecore edbus
+Version: @VERSION@
+Libs: -L${libdir} -leconnman
+Cflags: -I${includedir}
-I$(top_srcdir)/src/lib/hal \
-I$(top_srcdir)/src/lib/nm \
-I$(top_srcdir)/src/lib/notification \
+-I$(top_srcdir)/src/lib/connman \
@EDBUS_CFLAGS@ \
@EINA_CFLAGS@
if BUILD_ENOTIFY
ENOTIFY_PROG = e_dbus_notify e_dbus_notification_daemon e-notify-send
endif
+if BUILD_ECONNMAN
+ECONNMAN_PROG = e_dbus_connman_test
+ECONNMAN_PROG_NOINST = e_dbus_connman_test_api
+endif
+
+bin_PROGRAMS = \
+$(EDBUS_PROG) \
+$(EHAL_PROG) \
+$(ENM_PROG) \
+$(ENOTIFY_PROG) \
+$(ECONNMAN_PROG)
-bin_PROGRAMS = $(EDBUS_PROG) $(EHAL_PROG) $(ENM_PROG) $(ENOTIFY_PROG)
+noinst_PROGRAMS = \
+$(ECONNMAN_PROG_NOINST)
e_dbus_test_SOURCES = \
test.c
e_notify_send_CPPFLAGS = $(EDBUS_CPPFLAGS)
e_notify_send_LDADD = $(top_builddir)/src/lib/dbus/libedbus.la $(top_builddir)/src/lib/notification/libenotify.la
e_notify_send_DEPENDENCIES = $(top_builddir)/src/lib/dbus/libedbus.la $(top_builddir)/src/lib/notification/libenotify.la
-endif
+endif
+
+if BUILD_ECONNMAN
+e_dbus_connman_test_SOURCES = e_dbus_connman_test.c
+e_dbus_connman_test_CPPFLAGS = $(EDBUS_CPPFLAGS)
+e_dbus_connman_test_LDADD = $(top_builddir)/src/lib/dbus/libedbus.la $(top_builddir)/src/lib/connman/libeconnman.la
+e_dbus_connman_test_DEPENDENCIES = $(top_builddir)/src/lib/dbus/libedbus.la $(top_builddir)/src/lib/connman/libeconnman.la
+
+e_dbus_connman_test_api_SOURCES = e_dbus_connman_test_api.c
+e_dbus_connman_test_api_CPPFLAGS = $(EDBUS_CPPFLAGS)
+e_dbus_connman_test_api_LDADD = $(top_builddir)/src/lib/dbus/libedbus.la $(top_builddir)/src/lib/connman/libeconnman.la
+e_dbus_connman_test_api_DEPENDENCIES = $(top_builddir)/src/lib/dbus/libedbus.la $(top_builddir)/src/lib/connman/libeconnman.la
+endif
--- /dev/null
+#include "E_Connman.h"
+#include <stdio.h>
+#include <string.h>
+#include <ctype.h>
+#include <errno.h>
+
+static void
+_elements_print(E_Connman_Element **elements, int count)
+{
+ int i;
+ for (i = 0; i < count; i++)
+ {
+ printf("--- element %d:\n", i);
+ e_connman_element_print(stdout, elements[i]);
+ }
+ free(elements);
+ printf("END: all elements count = %d\n", count);
+}
+
+static int
+_on_element_add(void *data, int type, void *info)
+{
+ E_Connman_Element *element = info;
+ printf(">>> %s\n", element->path);
+ return 1;
+}
+
+static int
+_on_element_del(void *data, int type, void *info)
+{
+ E_Connman_Element *element = info;
+ printf("<<< %s\n", element->path);
+ return 1;
+}
+
+static int
+_on_element_updated(void *data, int type, void *info)
+{
+ E_Connman_Element *element = info;
+ printf("!!! %s\n", element->path);
+ e_connman_element_print(stderr, element);
+ return 1;
+}
+
+static int
+_on_cmd_quit(char *cmd, char *args)
+{
+ fputs("Bye!\n", stderr);
+ ecore_main_loop_quit();
+ return 0;
+}
+
+static int
+_on_cmd_sync(char *cmd, char *args)
+{
+ e_connman_manager_sync_elements();
+ return 1;
+}
+
+static char *
+_tok(char *p)
+{
+ p = strchr(p, ' ');
+ if (!p)
+ return NULL;
+
+ *p = '\0';
+ p++;
+ while (isspace(*p))
+ p++;
+ if (*p == '\0')
+ return NULL;
+
+ return p;
+}
+
+static int
+_on_cmd_get_all(char *cmd, char *args)
+{
+ E_Connman_Element **elements;
+ char *type;
+ unsigned int count;
+ bool ret;
+
+ if (!args)
+ type = NULL;
+ else
+ type = args;
+
+ if (type)
+ ret = e_connman_elements_get_all_type(type, &count, &elements);
+ else
+ ret = e_connman_elements_get_all(&count, &elements);
+
+ if (!ret)
+ fputs("ERROR: could not get elements\n", stderr);
+ else
+ {
+ printf("BEG: all elements type=%s count = %d\n", type, count);
+ _elements_print(elements, count);
+ }
+
+ return 1;
+}
+
+static E_Connman_Element *
+_element_from_args(char *args, char **next_args)
+{
+ E_Connman_Element *element;
+
+ if (!args)
+ {
+ fputs("ERROR: missing element path\n", stderr);
+ *next_args = NULL;
+ return NULL;
+ }
+
+ *next_args = _tok(args);
+ element = e_connman_element_get(args);
+ if (!element)
+ fprintf(stderr, "ERROR: no element called \"%s\".\n", args);
+
+ return element;
+}
+
+static int
+_on_cmd_print(char *cmd, char *args)
+{
+ char *next_args;
+ E_Connman_Element *element = _element_from_args(args, &next_args);
+ if (element)
+ e_connman_element_print(stdout, element);
+ return 1;
+}
+
+static int
+_on_cmd_get_properties(char *cmd, char *args)
+{
+ char *next_args;
+ E_Connman_Element *element = _element_from_args(args, &next_args);
+ if (element)
+ e_connman_element_properties_sync(element);
+ return 1;
+}
+
+static int
+_on_cmd_property_set(char *cmd, char *args)
+{
+ char *next_args, *name, *p;
+ E_Connman_Element *element = _element_from_args(args, &next_args);
+ void *value;
+ long vlong;
+ unsigned short vu16;
+ unsigned int vu32;
+ int type;
+
+ if (!element)
+ return 1;
+
+ if (!next_args)
+ {
+ fputs("ERROR: missing parameters name, type and value.\n", stderr);
+ return 1;
+ }
+
+ name = next_args;
+ p = _tok(name);
+ if (!p)
+ {
+ fputs("ERROR: missing parameters type and value.\n", stderr);
+ return 1;
+ }
+
+ next_args = _tok(p);
+ if (!next_args)
+ {
+ fputs("ERROR: missing parameter value.\n", stderr);
+ return 1;
+ }
+
+ type = p[0];
+ switch (type)
+ {
+ case DBUS_TYPE_BOOLEAN:
+ vlong = !!atol(next_args);
+ value = (void *)vlong;
+ fprintf(stderr, "DBG: boolean is: %ld\n", vlong);
+ break;
+ case DBUS_TYPE_UINT16:
+ vu16 = strtol(next_args, &p, 0);
+ if (p == next_args)
+ {
+ fprintf(stderr, "ERROR: invalid number \"%s\".\n", next_args);
+ return 1;
+ }
+ value = &vu16;
+ fprintf(stderr, "DBG: u16 is: %hu\n", vu16);
+ break;
+ case DBUS_TYPE_UINT32:
+ vu32 = strtol(next_args, &p, 0);
+ if (p == next_args)
+ {
+ fprintf(stderr, "ERROR: invalid number \"%s\".\n", next_args);
+ return 1;
+ }
+ value = &vu32;
+ fprintf(stderr, "DBG: u16 is: %u\n", vu32);
+ break;
+ case DBUS_TYPE_STRING:
+ case DBUS_TYPE_OBJECT_PATH:
+ p = next_args + strlen(next_args);
+ if (p > next_args)
+ p--;
+ while (p > next_args && isspace(*p))
+ p--;
+ if (p <= next_args)
+ {
+ fprintf(stderr, "ERROR: invalid string \"%s\".\n", next_args);
+ }
+ p[1] = '\0';
+ value = next_args;
+ fprintf(stderr, "DBG: string is: \"%s\"\n", next_args);
+ break;
+ default:
+ fprintf(stderr, "ERROR: don't know how to parse type '%c' (%d)\n",
+ type, type);
+ return 1;
+ }
+
+ fprintf(stderr, "set_property %s [%p] %s %c %p...\n",
+ args, element, name, type, value);
+ e_connman_element_property_set(element, name, type, value);
+ return 1;
+}
+
+
+/* Manager Commands */
+
+static int
+_on_cmd_manager_get(char *cmd, char *args)
+{
+ E_Connman_Element *element;
+ element = e_connman_manager_get();
+ e_connman_element_print(stderr, element);
+ return 1;
+}
+
+static int
+_on_cmd_manager_get_profiles(char *cmd, char *args)
+{
+ unsigned int count;
+ E_Connman_Element **profiles;
+
+ if (!e_connman_manager_profiles_get(&count, &profiles))
+ {
+ fputs("ERROR: can't get profiles\n", stderr);
+ return 1;
+ }
+ printf("BEG: all manager profiles elements count = %d\n", count);
+ _elements_print(profiles, count);
+ return 1;
+}
+
+static int
+_on_cmd_manager_get_devices(char *cmd, char *args)
+{
+ unsigned int count;
+ E_Connman_Element **devices;
+
+ if (!e_connman_manager_devices_get(&count, &devices))
+ {
+ fputs("ERROR: can't get devices\n", stderr);
+ return 1;
+ }
+ printf("BEG: all manager devices elements count = %d\n", count);
+ _elements_print(devices, count);
+ return 1;
+}
+
+static int
+_on_cmd_manager_get_connections(char *cmd, char *args)
+{
+ unsigned int count;
+ E_Connman_Element **connections;
+
+ if (!e_connman_manager_connections_get(&count, &connections))
+ {
+ fputs("ERROR: can't get connections\n", stderr);
+ return 1;
+ }
+ printf("BEG: all manager connections elements count = %d\n", count);
+ _elements_print(connections, count);
+ return 1;
+}
+
+static int
+_on_cmd_manager_register_agent(char *cmd, char *args)
+{
+ char *path;
+
+ if (!args)
+ {
+ fputs("ERROR: missing the object path\n", stderr);
+ return 1;
+ }
+
+ path = args;
+ if (e_connman_manager_register_agent(path, NULL, NULL))
+ printf(":::Registering agent %s...\n", path);
+ else
+ fprintf(stderr, "ERROR: can't register agent %s\n", path);
+
+ return 1;
+}
+
+static int
+_on_cmd_manager_unregister_agent(char *cmd, char *args)
+{
+ char *path;
+
+ if (!args)
+ {
+ fputs("ERROR: missing the object path\n", stderr);
+ return 1;
+ }
+
+ path = args;
+ if (e_connman_manager_unregister_agent(path, NULL, NULL))
+ printf(":::Unregistering agent %s...\n", path);
+ else
+ fprintf(stderr, "ERROR: can't unregister agent %s\n", path);
+
+ return 1;
+}
+
+static int
+_on_cmd_manager_get_state(char *cmd, char *args)
+{
+ const char *state;
+ if (e_connman_manager_state_get(&state))
+ printf(":::Manager state = \"%s\"\n", state);
+ else
+ fputs("ERROR: can't get manager state\n", stderr);
+ return 1;
+}
+
+static int
+_on_cmd_manager_get_policy(char *cmd, char *args)
+{
+ const char *policy;
+ if (e_connman_manager_policy_get(&policy))
+ printf(":::Manager policy = \"%s\"\n", policy);
+ else
+ fputs("ERROR: can't get manager policy\n", stderr);
+ return 1;
+}
+
+static int
+_on_cmd_manager_set_policy(char *cmd, char *args)
+{
+ char *policy;
+ if (!args)
+ {
+ fputs("ERROR: missing the policy value\n", stderr);
+ return 1;
+ }
+ _tok(args);
+ policy = args;
+ if (e_connman_manager_policy_set(policy, NULL, NULL))
+ printf(":::Manager policy set to \"%s\"\n", policy);
+ else
+ fputs("ERROR: can't set manager policy\n", stderr);
+ return 1;
+}
+
+static int
+_on_cmd_manager_get_offline_mode(char *cmd, char *args)
+{
+ bool offline;
+ if (e_connman_manager_offline_mode_get(&offline))
+ printf(":::Manager Offline Mode = %hhu\n", offline);
+ else
+ fputs("ERROR: can't get manager offline mode\n", stderr);
+ return 1;
+}
+
+static int
+_on_cmd_manager_set_offline_mode(char *cmd, char *args)
+{
+ bool offline;
+ if (!args)
+ {
+ fputs("ERROR: missing the offline mode value\n", stderr);
+ return 1;
+ }
+ _tok(args);
+ offline = !!atol(args);
+ if (e_connman_manager_offline_mode_set(offline, NULL, NULL))
+ printf(":::Manager Offline Mode set to %hhu\n", offline);
+ else
+ fputs("ERROR: can't set manager offline mode\n", stderr);
+ return 1;
+}
+
+/* Device Commands */
+
+static int
+_on_cmd_device_create_network(char *cmd, char *args)
+{
+ char *path;
+ E_Connman_Element *e;
+
+ if (!args)
+ {
+ fputs("ERROR: missing the device path\n", stderr);
+ return 1;
+ }
+ _tok(args);
+ path = args;
+ e = e_connman_device_get(path);
+ if (e_connman_device_network_create(e, NULL, NULL))
+ printf(":::Creating Network %s...\n", path);
+ else
+ fputs("ERROR: can't create network\n", stderr);
+ return 1;
+}
+
+static int
+_on_cmd_device_remove_network(char *cmd, char *args)
+{
+ char *path, *device_path;
+ E_Connman_Element *e;
+
+ if (!args)
+ {
+ fputs("ERROR: missing the device path\n", stderr);
+ return 1;
+ }
+ device_path = args;
+ path = _tok(args);
+
+ if (!path)
+ {
+ fputs("ERROR: missing the object network\n", stderr);
+ return 1;
+ }
+ _tok(path);
+
+ e = e_connman_device_get(device_path);
+ if (e_connman_device_network_remove(e, path, NULL, NULL))
+ printf(":::Removing Network %s...\n", path);
+ else
+ fputs("ERROR: can't remove network\n", stderr);
+ return 1;
+}
+
+static int
+_on_cmd_device_propose_scan(char *cmd, char *args)
+{
+ char *path;
+ E_Connman_Element *e;
+
+ if (!args)
+ {
+ fputs("ERROR: missing the device path\n", stderr);
+ return 1;
+ }
+ _tok(args);
+ path = args;
+
+ e = e_connman_device_get(path);
+ if (e_connman_device_propose_scan(e, NULL, NULL))
+ printf(":::Proposing scan %s...\n", path);
+ else
+ fputs("ERROR: can't propose scan\n", stderr);
+ return 1;
+}
+
+static int
+_on_cmd_device_get_name(char *cmd, char *args)
+{
+ const char *name, *path;
+ E_Connman_Element *e;
+
+ if (!args)
+ {
+ fputs("ERROR: missing the device path\n", stderr);
+ return 1;
+ }
+ _tok(args);
+ path = args;
+
+ e = e_connman_device_get(path);
+ if (e_connman_device_name_get(e, &name))
+ printf(":::Device %s Name = \"%s\"\n", path, name);
+ else
+ fputs("ERROR: can't get device name\n", stderr);
+ return 1;
+}
+
+static int
+_on_cmd_device_get_type(char *cmd, char *args)
+{
+ const char *type, *path;
+ E_Connman_Element *e;
+
+ if (!args)
+ {
+ fputs("ERROR: missing the device path\n", stderr);
+ return 1;
+ }
+ _tok(args);
+ path = args;
+
+ e = e_connman_device_get(path);
+ if (e_connman_device_type_get(e, &type))
+ printf(":::Device %s Type = \"%s\"\n", path, type);
+ else
+ fputs("ERROR: can't get device type\n", stderr);
+ return 1;
+}
+
+static int
+_on_cmd_device_get_interface(char *cmd, char *args)
+{
+ const char *interface, *path;
+ E_Connman_Element *e;
+
+ if (!args)
+ {
+ fputs("ERROR: missing the device path\n", stderr);
+ return 1;
+ }
+ _tok(args);
+ path = args;
+
+ e = e_connman_device_get(path);
+ if (e_connman_device_interface_get(e, &interface))
+ printf(":::Device %s Interface = \"%s\"\n", path, interface);
+ else
+ fputs("ERROR: can't get device interface\n", stderr);
+ return 1;
+}
+
+static int
+_on_cmd_device_get_policy(char *cmd, char *args)
+{
+ const char *policy, *path;
+ E_Connman_Element *e;
+
+ if (!args)
+ {
+ fputs("ERROR: missing the device path\n", stderr);
+ return 1;
+ }
+ _tok(args);
+ path = args;
+
+ e = e_connman_device_get(path);
+ if (e_connman_device_policy_get(e, &policy))
+ printf(":::Device %s Policy = \"%s\"\n", path, policy);
+ else
+ fputs("ERROR: can't get device policy\n", stderr);
+ return 1;
+}
+
+static int
+_on_cmd_device_set_policy(char *cmd, char *args)
+{
+ char *policy;
+ const char *device_path;
+ E_Connman_Element *e;
+
+ if (!args)
+ {
+ fputs("ERROR: missing the device path\n", stderr);
+ return 1;
+ }
+ device_path = args;
+ policy = _tok(args);
+
+ if (!policy)
+ {
+ fputs("ERROR: missing the policy value\n", stderr);
+ return 1;
+ }
+ _tok(policy);
+
+ e = e_connman_device_get(device_path);
+ if (e_connman_device_policy_set(e, policy, NULL, NULL))
+ printf(":::Device %s policy set to \"%s\"\n", device_path, policy);
+ else
+ fputs("ERROR: can't set device policy\n", stderr);
+ return 1;
+}
+
+static int
+_on_cmd_device_get_priority(char *cmd, char *args)
+{
+ char *path;
+ unsigned char priority;
+ E_Connman_Element *e;
+
+ if (!args)
+ {
+ fputs("ERROR: missing the device path\n", stderr);
+ return 1;
+ }
+ _tok(args);
+ path = args;
+
+ e = e_connman_device_get(path);
+ if (e_connman_device_priority_get(e, &priority))
+ printf(":::Device %s Priority = %#02hhx (%d)\n", path, priority, priority);
+ else
+ fputs("ERROR: can't get device priority\n", stderr);
+ return 1;
+}
+
+static int
+_on_cmd_device_set_priority(char *cmd, char *args)
+{
+ char *next_args, *device_path, *p;
+ unsigned char priority;
+ E_Connman_Element *e;
+
+ if (!args)
+ {
+ fputs("ERROR: missing the device path\n", stderr);
+ return 1;
+ }
+ device_path = args;
+ next_args = _tok(args);
+ if (!next_args)
+ {
+ fputs("ERROR: missing the priority value\n", stderr);
+ return 1;
+ }
+ _tok(next_args);
+ priority = strtol(next_args, &p, 0);
+ if (p == next_args)
+ {
+ fprintf(stderr, "ERROR: invalid number \"%s\".\n", next_args);
+ return 1;
+ }
+
+ e = e_connman_device_get(device_path);
+ if (e_connman_device_priority_set(e, priority, NULL, NULL))
+ printf(":::Device %s priority set to %d\n", device_path, priority);
+ else
+ fputs("ERROR: can't set device priority\n", stderr);
+ return 1;
+}
+
+static int
+_on_cmd_device_get_powered(char *cmd, char *args)
+{
+ char *path;
+ bool powered;
+ E_Connman_Element *e;
+
+ if (!args)
+ {
+ fputs("ERROR: missing the device path\n", stderr);
+ return 1;
+ }
+ _tok(args);
+ path = args;
+
+ e = e_connman_device_get(path);
+ if (e_connman_device_powered_get(e, &powered))
+ printf(":::Device %s Powered = %hhu\n", path, powered);
+ else
+ fputs("ERROR: can't get device powered\n", stderr);
+ return 1;
+}
+
+static int
+_on_cmd_device_set_powered(char *cmd, char *args)
+{
+ char *device_path, *next_args;
+ bool powered;
+ E_Connman_Element *e;
+
+ if (!args)
+ {
+ fputs("ERROR: missing the device path\n", stderr);
+ return 1;
+ }
+ device_path = args;
+ next_args = _tok(args);
+ if (!next_args)
+ {
+ fputs("ERROR: missing the powered value\n", stderr);
+ return 1;
+ }
+ powered = !!atol(next_args);
+
+ e = e_connman_device_get(device_path);
+ if (e_connman_device_powered_set(e, powered, NULL, NULL))
+ printf(":::Device %s powered set to %hhu\n", device_path, powered);
+ else
+ fputs("ERROR: can't set device powered\n", stderr);
+ return 1;
+}
+
+static int
+_on_cmd_device_get_scan_interval(char *cmd, char *args)
+{
+ char *path;
+ unsigned short scan_interval;
+ E_Connman_Element *e;
+
+ if (!args)
+ {
+ fputs("ERROR: missing the device path\n", stderr);
+ return 1;
+ }
+ _tok(args);
+ path = args;
+
+ e = e_connman_device_get(path);
+ if (e_connman_device_scan_interval_get(e, &scan_interval))
+ printf(":::Device %s ScanInterval = %hu\n", path, scan_interval);
+ else
+ fputs("ERROR: can't get device scan interval\n", stderr);
+ return 1;
+}
+
+static int
+_on_cmd_device_set_scan_interval(char *cmd, char *args)
+{
+ char *device_path, *next_args, *p;
+ unsigned short scan_interval;
+ E_Connman_Element *e;
+
+ if (!args)
+ {
+ fputs("ERROR: missing the device path\n", stderr);
+ return 1;
+ }
+ device_path = args;
+ next_args = _tok(args);
+ if (!next_args)
+ {
+ fputs("ERROR: missing the scan interval value\n", stderr);
+ return 1;
+ }
+ scan_interval = strtol(next_args, &p, 0);
+ if (p == next_args)
+ {
+ fprintf(stderr, "ERROR: invalid number \"%s\".\n", next_args);
+ return 1;
+ }
+
+ e = e_connman_device_get(device_path);
+ if (e_connman_device_scan_interval_set(e, scan_interval, NULL, NULL))
+ printf(":::Device %s scan interval set to %hu\n", device_path, scan_interval);
+ else
+ fputs("ERROR: can't set device scan interval\n", stderr);
+ return 1;
+}
+
+static int
+_on_cmd_device_get_scanning(char *cmd, char *args)
+{
+ char *path;
+ bool scanning;
+ E_Connman_Element *e;
+
+ if (!args)
+ {
+ fputs("ERROR: missing the device path\n", stderr);
+ return 1;
+ }
+ _tok(args);
+ path = args;
+
+ e = e_connman_device_get(path);
+ if (e_connman_device_scanning_get(e, &scanning))
+ printf(":::Device %s Scanning = %hhu\n", path, scanning);
+ else
+ fputs("ERROR: can't get device scanning\n", stderr);
+ return 1;
+}
+
+static int
+_on_cmd_device_get_networks(char *cmd, char *args)
+{
+ E_Connman_Element **networks;
+ unsigned int count;
+ char *path;
+ E_Connman_Element *e;
+
+ if (!args)
+ {
+ fputs("ERROR: missing the device path\n", stderr);
+ return 1;
+ }
+ _tok(args);
+ path = args;
+
+ e = e_connman_device_get(path);
+ if (!e_connman_device_networks_get(e, &count, &networks))
+ {
+ fputs("ERROR: can't get networks\n", stderr);
+ return 1;
+ }
+
+ printf("BEG: all device network elements count = %d\n", count);
+ _elements_print(networks, count);
+ return 1;
+}
+
+/* Profile Commands */
+
+static int
+_on_cmd_profile_get_name(char *cmd, char *args)
+{
+ const char *name, *path;
+ E_Connman_Element *e;
+
+ if (!args)
+ {
+ fputs("ERROR: missing the profile path\n", stderr);
+ return 1;
+ }
+ _tok(args);
+ path = args;
+
+ e = e_connman_profile_get(path);
+ if (e_connman_profile_name_get(e, &name))
+ printf(":::Profile %s Name = \"%s\"\n", path, name);
+ else
+ fputs("ERROR: can't get profile name\n", stderr);
+ return 1;
+}
+
+/* Connection Commands */
+
+static int
+_on_cmd_connection_get_type(char *cmd, char *args)
+{
+ const char *type, *path;
+ E_Connman_Element *e;
+
+ if (!args)
+ {
+ fputs("ERROR: missing the connection path\n", stderr);
+ return 1;
+ }
+ _tok(args);
+ path = args;
+
+ e = e_connman_connection_get(path);
+ if (e_connman_connection_type_get(e, &type))
+ printf(":::Connection %s Type = \"%s\"\n", path, type);
+ else
+ fputs("ERROR: can't get connection type\n", stderr);
+ return 1;
+}
+
+static int
+_on_cmd_connection_get_interface(char *cmd, char *args)
+{
+ const char *interface, *path;
+ E_Connman_Element *e;
+
+ if (!args)
+ {
+ fputs("ERROR: missing the connection path\n", stderr);
+ return 1;
+ }
+ _tok(args);
+ path = args;
+
+ e = e_connman_connection_get(path);
+ if (e_connman_connection_interface_get(e, &interface))
+ printf(":::Connection %s Interface = \"%s\"\n", path, interface);
+ else
+ fputs("ERROR: can't get connection type\n", stderr);
+ return 1;
+}
+
+static int
+_on_cmd_connection_get_device(char *cmd, char *args)
+{
+ E_Connman_Element *e, *device;
+ char *path;
+
+ if (!args)
+ {
+ fputs("ERROR: missing the connection path\n", stderr);
+ return 1;
+ }
+ _tok(args);
+ path = args;
+
+ e = e_connman_connection_get(path);
+ if (!e_connman_connection_device_get(e, &device))
+ fputs("ERROR: can't get connection device\n", stderr);
+ else
+ e_connman_element_print(stderr, device);
+ return 1;
+}
+
+static int
+_on_cmd_connection_get_network(char *cmd, char *args)
+{
+ E_Connman_Element *e, *network;
+ char *path;
+
+ if (!args)
+ {
+ fputs("ERROR: missing the connection path\n", stderr);
+ return 1;
+ }
+ _tok(args);
+ path = args;
+
+ e = e_connman_connection_get(path);
+ if (!e_connman_connection_network_get(e, &network))
+ fputs("ERROR: can't get connection network\n", stderr);
+ else
+ e_connman_element_print(stderr, network);
+ return 1;
+}
+
+static int
+_on_cmd_connection_get_strength(char *cmd, char *args)
+{
+ char *path;
+ unsigned char strength;
+ E_Connman_Element *e;
+
+ if (!args)
+ {
+ fputs("ERROR: missing the connection path\n", stderr);
+ return 1;
+ }
+ _tok(args);
+ path = args;
+
+ e = e_connman_connection_get(path);
+ if (e_connman_connection_strength_get(e, &strength))
+ printf(":::Connection %s Strength = %#02hhx (%d)\n", path, strength, strength);
+ else
+ fputs("ERROR: can't get connection strength\n", stderr);
+ return 1;
+}
+
+static int
+_on_cmd_connection_get_default(char *cmd, char *args)
+{
+ char *path;
+ bool connection_default;
+ E_Connman_Element *e;
+
+ if (!args)
+ {
+ fputs("ERROR: missing the connection path\n", stderr);
+ return 1;
+ }
+ _tok(args);
+ path = args;
+
+ e = e_connman_connection_get(path);
+ if (e_connman_connection_default_get(e, &connection_default))
+ printf(":::Connection %s Default = %hhu\n", path, connection_default);
+ else
+ fputs("ERROR: can't get connection default\n", stderr);
+ return 1;
+}
+
+static int
+_on_cmd_connection_get_ipv4_method(char *cmd, char *args)
+{
+ const char *method, *path;
+ E_Connman_Element *e;
+
+ if (!args)
+ {
+ fputs("ERROR: missing the connection path\n", stderr);
+ return 1;
+ }
+ _tok(args);
+ path = args;
+
+ e = e_connman_connection_get(path);
+ if (e_connman_connection_ipv4_method_get(e, &method))
+ printf(":::Connection %s IPv4 Method = \"%s\"\n", path, method);
+ else
+ fputs("ERROR: can't get connection ipv4 method\n", stderr);
+ return 1;
+}
+
+static int
+_on_cmd_connection_get_ipv4_address(char *cmd, char *args)
+{
+ const char *address, *path;
+ E_Connman_Element *e;
+
+ if (!args)
+ {
+ fputs("ERROR: missing the connection path\n", stderr);
+ return 1;
+ }
+ _tok(args);
+ path = args;
+
+ e = e_connman_connection_get(path);
+ if (e_connman_connection_ipv4_address_get(e, &address))
+ printf(":::Connection %s IPv4 Address = \"%s\"\n", path, address);
+ else
+ fputs("ERROR: can't get connection ipv4 address\n", stderr);
+ return 1;
+}
+
+/* Network Commands */
+
+static int
+_on_cmd_network_connect(char *cmd, char *args)
+{
+ char *path;
+ E_Connman_Element *e;
+
+ if (!args)
+ {
+ fputs("ERROR: missing the network path\n", stderr);
+ return 1;
+ }
+ _tok(args);
+ path = args;
+
+ e = e_connman_network_get(path);
+ if (e_connman_network_connect(e, NULL, NULL))
+ printf(":::Connecting to Network %s...\n", path);
+ else
+ fputs("ERROR: can't connect to network\n", stderr);
+ return 1;
+}
+
+static int
+_on_cmd_network_disconnect(char *cmd, char *args)
+{
+ char *path;
+ E_Connman_Element *e;
+
+ if (!args)
+ {
+ fputs("ERROR: missing the network path\n", stderr);
+ return 1;
+ }
+ _tok(args);
+ path = args;
+
+ e = e_connman_network_get(path);
+ if (e_connman_network_disconnect(e, NULL, NULL))
+ printf(":::Disconnecting Network %s...\n", path);
+ else
+ fputs("ERROR: can't disconnect network\n", stderr);
+ return 1;
+}
+
+static int
+_on_cmd_network_get_name(char *cmd, char *args)
+{
+ const char *name, *path;
+ E_Connman_Element *e;
+
+ if (!args)
+ {
+ fputs("ERROR: missing the network path\n", stderr);
+ return 1;
+ }
+ _tok(args);
+ path = args;
+
+ e = e_connman_network_get(path);
+ if (e_connman_network_name_get(e, &name))
+ printf(":::Network %s Name = \"%s\"\n", path, name);
+ else
+ fputs("ERROR: can't get network name\n", stderr);
+ return 1;
+}
+
+static int
+_on_cmd_network_get_available(char *cmd, char *args)
+{
+ const char *path;
+ bool available;
+ E_Connman_Element *e;
+
+ if (!args)
+ {
+ fputs("ERROR: missing the network path\n", stderr);
+ return 1;
+ }
+ _tok(args);
+ path = args;
+
+ e = e_connman_network_get(path);
+ if (e_connman_network_available_get(e, &available))
+ printf(":::Network %s Available = %hhu\n", path, available);
+ else
+ fputs("ERROR: can't get network available\n", stderr);
+ return 1;
+}
+
+static int
+_on_cmd_network_get_connected(char *cmd, char *args)
+{
+ char *path;
+ bool connected;
+ E_Connman_Element *e;
+
+ if (!args)
+ {
+ fputs("ERROR: missing the network path\n", stderr);
+ return 1;
+ }
+ _tok(args);
+ path = args;
+
+ e = e_connman_network_get(path);
+ if (e_connman_network_connected_get(e, &connected))
+ printf(":::Network %s Connected = %hhu\n", path, connected);
+ else
+ fputs("ERROR: can't get network connected\n", stderr);
+ return 1;
+}
+
+static int
+_on_cmd_network_get_remember(char *cmd, char *args)
+{
+ char *path;
+ bool remember;
+ E_Connman_Element *e;
+
+ if (!args)
+ {
+ fputs("ERROR: missing the network path\n", stderr);
+ return 1;
+ }
+ _tok(args);
+ path = args;
+
+ e = e_connman_network_get(path);
+ if (e_connman_network_remember_get(e, &remember))
+ printf(":::Network %s Remember = %hhu\n", path, remember);
+ else
+ fputs("ERROR: can't get network remember\n", stderr);
+ return 1;
+}
+
+static int
+_on_cmd_network_set_remember(char *cmd, char *args)
+{
+ char *network_path, *next_args;
+ bool remember;
+ E_Connman_Element *e;
+
+ if (!args)
+ {
+ fputs("ERROR: missing the network path\n", stderr);
+ return 1;
+ }
+ network_path = args;
+ next_args = _tok(args);
+ if (!next_args)
+ {
+ fputs("ERROR: missing the remember value\n", stderr);
+ return 1;
+ }
+ _tok(next_args);
+ remember = !!atol(next_args);
+
+ e = e_connman_network_get(network_path);
+ if (e_connman_network_remember_set(e, remember, NULL, NULL))
+ printf(":::Network %s remember set to %d\n", network_path, remember);
+ else
+ fputs("ERROR: can't set network remember\n", stderr);
+ return 1;
+}
+
+static int
+_on_cmd_network_get_strength(char *cmd, char *args)
+{
+ char *path;
+ unsigned char strength;
+ E_Connman_Element *e;
+
+ if (!args)
+ {
+ fputs("ERROR: missing the network path\n", stderr);
+ return 1;
+ }
+ _tok(args);
+ path = args;
+
+ e = e_connman_network_get(path);
+ if (e_connman_network_strength_get(e, &strength))
+ printf(":::Network %s Strength = %#02hhx (%d)\n", path, strength, strength);
+ else
+ fputs("ERROR: can't get network strength\n", stderr);
+ return 1;
+}
+
+static int
+_on_cmd_network_get_device(char *cmd, char *args)
+{
+ E_Connman_Element *e, *device;
+ char *path;
+
+ if (!args)
+ {
+ fputs("ERROR: missing the network path\n", stderr);
+ return 1;
+ }
+ _tok(args);
+ path = args;
+
+ e = e_connman_network_get(path);
+ if (!e_connman_network_device_get(e, &device))
+ fputs("ERROR: can't get network device\n", stderr);
+ else
+ e_connman_element_print(stderr, device);
+ return 1;
+}
+
+static int
+_on_cmd_network_get_wifi_ssid(char *cmd, char *args)
+{
+ unsigned char *bytes;
+ char *path;
+ unsigned int i, count;
+ E_Connman_Element *e;
+
+ if (!args)
+ {
+ fputs("ERROR: missing the network path\n", stderr);
+ return 1;
+ }
+ _tok(args);
+ path = args;
+
+ e = e_connman_network_get(path);
+ if (e_connman_network_wifi_ssid_get(e, &count, &bytes))
+ {
+ printf(":::Network %s Wifi SSID = ", path);
+ for (i = 0; i < count; i++)
+ printf("%#02hhx (\"%c\"), ", bytes[i], bytes[i]);
+ printf("\n");
+ }
+ else
+ fputs("ERROR: can't get network wifi ssid\n", stderr);
+ return 1;
+}
+
+static int
+_on_cmd_network_get_wifi_mode(char *cmd, char *args)
+{
+ const char *wifi_mode, *path;
+ E_Connman_Element *e;
+
+ if (!args)
+ {
+ fputs("ERROR: missing the network path\n", stderr);
+ return 1;
+ }
+ _tok(args);
+ path = args;
+
+ e = e_connman_network_get(path);
+ if (e_connman_network_wifi_mode_get(e, &wifi_mode))
+ printf(":::Network %s Wifi Mode = \"%s\"\n", path, wifi_mode);
+ else
+ fputs("ERROR: can't get network wifi mode\n", stderr);
+ return 1;
+}
+
+static int
+_on_cmd_network_set_wifi_mode(char *cmd, char *args)
+{
+ char *wifi_mode;
+ const char *network_path;
+ E_Connman_Element *e;
+
+ if (!args)
+ {
+ fputs("ERROR: missing the network path\n", stderr);
+ return 1;
+ }
+ network_path = args;
+ wifi_mode = _tok(args);
+
+ if (!wifi_mode)
+ {
+ fputs("ERROR: missing the wifi mode value\n", stderr);
+ return 1;
+ }
+ _tok(wifi_mode);
+
+ e = e_connman_network_get(network_path);
+ if (e_connman_network_wifi_mode_set(e, wifi_mode, NULL, NULL))
+ printf(":::Network %s wifi mode set to \"%s\"\n", network_path, wifi_mode);
+ else
+ fputs("ERROR: can't set network wifi mode\n", stderr);
+ return 1;
+}
+
+static int
+_on_cmd_network_get_wifi_security(char *cmd, char *args)
+{
+ const char *wifi_security, *path;
+ E_Connman_Element *e;
+
+ if (!args)
+ {
+ fputs("ERROR: missing the network path\n", stderr);
+ return 1;
+ }
+ _tok(args);
+ path = args;
+
+ e = e_connman_network_get(path);
+ if (e_connman_network_wifi_security_get(e, &wifi_security))
+ printf(":::Network %s Wifi Security = \"%s\"\n", path, wifi_security);
+ else
+ fputs("ERROR: can't get network wifi security\n", stderr);
+ return 1;
+}
+
+static int
+_on_cmd_network_set_wifi_security(char *cmd, char *args)
+{
+ char *wifi_security, *network_path;
+ E_Connman_Element *e;
+
+ if (!args)
+ {
+ fputs("ERROR: missing the network path\n", stderr);
+ return 1;
+ }
+ network_path = args;
+ wifi_security = _tok(args);
+
+ if (!wifi_security)
+ {
+ fputs("ERROR: missing the wifi security value\n", stderr);
+ return 1;
+ }
+ _tok(wifi_security);
+
+ e = e_connman_network_get(network_path);
+ if (e_connman_network_wifi_security_set(e, wifi_security, NULL, NULL))
+ printf(":::Network %s wifi security set to \"%s\"\n", network_path, wifi_security);
+ else
+ fputs("ERROR: can't set network wifi security\n", stderr);
+ return 1;
+}
+
+static int
+_on_cmd_network_get_wifi_passphrase(char *cmd, char *args)
+{
+ const char *wifi_passphrase, *path;
+ E_Connman_Element *e;
+
+ if (!args)
+ {
+ fputs("ERROR: missing the network path\n", stderr);
+ return 1;
+ }
+ _tok(args);
+ path = args;
+
+ e = e_connman_network_get(path);
+ if (e_connman_network_wifi_passphrase_get(e, &wifi_passphrase))
+ printf(":::Network %s Wifi Passphrase = \"%s\"\n", path, wifi_passphrase);
+ else
+ fputs("ERROR: can't get network wifi passphrase\n", stderr);
+ return 1;
+}
+
+static int
+_on_cmd_network_set_wifi_passphrase(char *cmd, char *args)
+{
+ char *wifi_passphrase, *network_path;
+ E_Connman_Element *e;
+
+ if (!args)
+ {
+ fputs("ERROR: missing the network path\n", stderr);
+ return 1;
+ }
+ network_path = args;
+ wifi_passphrase = _tok(args);
+
+ if (!wifi_passphrase)
+ {
+ fputs("ERROR: missing the wifi passphrase value\n", stderr);
+ return 1;
+ }
+ _tok(wifi_passphrase);
+
+ e = e_connman_network_get(network_path);
+ if (e_connman_network_wifi_passphrase_set(e, wifi_passphrase, NULL, NULL))
+ printf(":::Network %s wifi passphrase set to \"%s\"\n", network_path, wifi_passphrase);
+ else
+ fputs("ERROR: can't set network wifi passphrase\n", stderr);
+ return 1;
+}
+
+
+static int
+_on_input(void *data, Ecore_Fd_Handler *fd_handler)
+{
+ char buf[256];
+ char *cmd, *args;
+ const struct {
+ const char *cmd;
+ int (*cb)(char *cmd, char *args);
+ } *itr, maps[] = {
+ {"quit", _on_cmd_quit},
+ {"sync", _on_cmd_sync},
+ {"get_all", _on_cmd_get_all},
+ {"print", _on_cmd_print},
+ {"get_properties", _on_cmd_get_properties},
+ {"set_property", _on_cmd_property_set},
+ {"manager_get", _on_cmd_manager_get},
+ {"manager_get_profiles", _on_cmd_manager_get_profiles},
+ {"manager_get_devices", _on_cmd_manager_get_devices},
+ {"manager_get_connections", _on_cmd_manager_get_connections},
+ {"manager_register_agent", _on_cmd_manager_register_agent},
+ {"manager_unregister_agent", _on_cmd_manager_unregister_agent},
+ {"manager_get_state", _on_cmd_manager_get_state},
+ {"manager_get_policy", _on_cmd_manager_get_policy},
+ {"manager_set_policy", _on_cmd_manager_set_policy},
+ {"manager_get_offline_mode", _on_cmd_manager_get_offline_mode},
+ {"manager_set_offline_mode", _on_cmd_manager_set_offline_mode},
+ {"device_create_network", _on_cmd_device_create_network},
+ {"device_remove_network", _on_cmd_device_remove_network},
+ {"device_propose_scan", _on_cmd_device_propose_scan},
+ {"device_get_name", _on_cmd_device_get_name},
+ {"device_get_type", _on_cmd_device_get_type},
+ {"device_get_interface", _on_cmd_device_get_interface},
+ {"device_get_policy", _on_cmd_device_get_policy},
+ {"device_set_policy", _on_cmd_device_set_policy},
+ {"device_get_priority", _on_cmd_device_get_priority},
+ {"device_set_priority", _on_cmd_device_set_priority},
+ {"device_get_powered", _on_cmd_device_get_powered},
+ {"device_set_powered", _on_cmd_device_set_powered},
+ {"device_get_scan_interval", _on_cmd_device_get_scan_interval},
+ {"device_set_scan_interval", _on_cmd_device_set_scan_interval},
+ {"device_get_scanning", _on_cmd_device_get_scanning},
+ {"device_get_networks", _on_cmd_device_get_networks},
+ {"profile_get_name", _on_cmd_profile_get_name},
+ {"connection_get_type", _on_cmd_connection_get_type},
+ {"connection_get_interface", _on_cmd_connection_get_interface},
+ {"connection_get_strength", _on_cmd_connection_get_strength},
+ {"connection_get_default", _on_cmd_connection_get_default},
+ {"connection_get_device", _on_cmd_connection_get_device},
+ {"connection_get_network", _on_cmd_connection_get_network},
+ {"connection_get_ipv4_method", _on_cmd_connection_get_ipv4_method},
+ {"connection_get_ipv4_address", _on_cmd_connection_get_ipv4_address},
+ {"network_connect", _on_cmd_network_connect},
+ {"network_disconnect", _on_cmd_network_disconnect},
+ {"network_get_name", _on_cmd_network_get_name},
+ {"network_get_available", _on_cmd_network_get_available},
+ {"network_get_connected", _on_cmd_network_get_connected},
+ {"network_get_remember", _on_cmd_network_get_remember},
+ {"network_set_remember", _on_cmd_network_set_remember},
+ {"network_get_strength", _on_cmd_network_get_strength},
+ {"network_get_device", _on_cmd_network_get_device},
+ {"network_get_wifi_ssid", _on_cmd_network_get_wifi_ssid},
+ {"network_get_wifi_mode", _on_cmd_network_get_wifi_mode},
+ {"network_set_wifi_mode", _on_cmd_network_set_wifi_mode},
+ {"network_get_wifi_security", _on_cmd_network_get_wifi_security},
+ {"network_set_wifi_security", _on_cmd_network_set_wifi_security},
+ {"network_get_wifi_passphrase", _on_cmd_network_get_wifi_passphrase},
+ {"network_set_wifi_passphrase", _on_cmd_network_set_wifi_passphrase},
+ {NULL, NULL}
+ };
+
+ if (ecore_main_fd_handler_active_get(fd_handler, ECORE_FD_ERROR))
+ {
+ fputs("ERROR: reading from stdin, exit\n", stderr);
+ return 0;
+ }
+
+ if (!ecore_main_fd_handler_active_get(fd_handler, ECORE_FD_READ))
+ {
+ fputs("ERROR: nothing to read?\n", stderr);
+ return 0;
+ }
+
+ if (!fgets(buf, sizeof(buf), stdin))
+ {
+ fprintf(stderr, "ERROR: could not read command: %s\n", strerror(errno));
+ ecore_main_loop_quit();
+ return 0;
+ }
+
+ cmd = buf;
+ while (isspace(*cmd))
+ cmd++;
+
+ args = strchr(cmd, ' ');
+ if (args)
+ {
+ char *p;
+
+ *args = '\0';
+ args++;
+
+ while (isspace(*args))
+ args++;
+
+ p = args + strlen(args) - 1;
+ if (*p == '\n')
+ *p = '\0';
+ }
+ else
+ {
+ char *p;
+
+ p = cmd + strlen(cmd) - 1;
+ if (*p == '\n')
+ *p = '\0';
+ }
+
+ if (strcmp(cmd, "help") == 0)
+ {
+ if (args)
+ {
+ printf("Commands with '%s' in the name:\n", args);
+ for (itr = maps; itr->cmd != NULL; itr++)
+ if (strstr(itr->cmd, args))
+ printf("\t%s\n", itr->cmd);
+ }
+ else
+ {
+ fputs("Commands:\n", stdout);
+ for (itr = maps; itr->cmd != NULL; itr++)
+ printf("\t%s\n", itr->cmd);
+ }
+ fputc('\n', stdout);
+ return 1;
+ }
+
+ for (itr = maps; itr->cmd != NULL; itr++)
+ if (strcmp(itr->cmd, cmd) == 0)
+ return itr->cb(cmd, args);
+
+ printf("unknown command \"%s\", args=%s\n", cmd, args);
+ return 1;
+}
+
+int
+main(int argc, char *argv[])
+{
+ E_DBus_Connection *c;
+
+ ecore_init();
+ e_dbus_init();
+ eina_init();
+
+ c = e_dbus_bus_get(DBUS_BUS_SYSTEM);
+ if (!c) {
+ printf("ERROR: can't connect to system session\n");
+ return -1;
+ }
+
+ e_connman_system_init(c);
+ ecore_event_handler_add(E_CONNMAN_EVENT_ELEMENT_ADD, _on_element_add, NULL);
+ ecore_event_handler_add(E_CONNMAN_EVENT_ELEMENT_DEL, _on_element_del, NULL);
+ ecore_event_handler_add(E_CONNMAN_EVENT_ELEMENT_UPDATED,
+ _on_element_updated, NULL);
+
+ ecore_main_fd_handler_add
+ (0, ECORE_FD_READ | ECORE_FD_ERROR, _on_input, NULL, NULL, NULL);
+
+ ecore_main_loop_begin();
+
+ e_connman_system_shutdown();
+
+ e_dbus_connection_close(c);
+ eina_shutdown();
+ e_dbus_shutdown();
+ ecore_shutdown();
+
+ fputs("DBG: clean exit.\n", stderr);
+
+ return 0;
+}
--- /dev/null
+#include "E_Connman.h"
+#include <stdio.h>
+#include <string.h>
+
+#define DBG(...) EINA_ERROR_PDBG(__VA_ARGS__)
+#define INF(...) EINA_ERROR_PINFO(__VA_ARGS__)
+#define WRN(...) EINA_ERROR_PWARN(__VA_ARGS__)
+#define ERR(...) EINA_ERROR_PERR(__VA_ARGS__)
+
+static int success = 0;
+static int failure = 0;
+static Ecore_Timer *exiter = NULL;
+
+static bool
+_test_string_get(E_Connman_Element *element, const char *name, bool (*func)(const E_Connman_Element *element, const char **value))
+{
+ const char *value;
+ bool ret;
+
+ INF("BEGIN: testing string get %s of element %s...\n", name, element->path);
+ ret = func(element, &value);
+ if (ret)
+ INF("SUCCESS: testing string get %s of element %s: %s\n",
+ name, element->path, value);
+ else
+ WRN("FAILURE: testing string get %s of element %s\n",
+ name, element->path);
+
+ return ret;
+}
+
+static bool
+_test_bool_get(E_Connman_Element *element, const char *name, bool (*func)(const E_Connman_Element *element, bool *value))
+{
+ bool value, ret;
+
+ INF("BEGIN: testing bool get %s of element %s...\n", name, element->path);
+ ret = func(element, &value);
+ if (ret)
+ INF("SUCCESS: testing bool get %s of element %s: %hhu\n",
+ name, element->path, value);
+ else
+ WRN("FAILURE: testing bool get %s of element %s\n",
+ name, element->path);
+
+ return ret;
+}
+
+static bool
+_test_uchar_get(E_Connman_Element *element, const char *name, bool (*func)(const E_Connman_Element *element, unsigned char *value))
+{
+ unsigned char value;
+ bool ret;
+
+ INF("BEGIN: testing uchar get %s of element %s...\n", name, element->path);
+ ret = func(element, &value);
+ if (ret)
+ INF("SUCCESS: testing uchar get %s of element %s: %hhu\n",
+ name, element->path, value);
+ else
+ WRN("FAILURE: testing uchar get %s of element %s\n",
+ name, element->path);
+
+ return ret;
+}
+
+static bool
+_test_ushort_get(E_Connman_Element *element, const char *name, bool (*func)(const E_Connman_Element *element, unsigned short *value))
+{
+ unsigned short value;
+ bool ret;
+
+ INF("BEGIN: testing ushort get %s of element %s...\n", name, element->path);
+ ret = func(element, &value);
+ if (ret)
+ INF("SUCCESS: testing ushort get %s of element %s: %hu\n",
+ name, element->path, value);
+ else
+ WRN("FAILURE: testing ushort get %s of element %s\n",
+ name, element->path);
+
+ return ret;
+}
+
+static bool
+_test_uchar_array_get(E_Connman_Element *element, const char *name, bool (*func)(const E_Connman_Element *element, unsigned int *count, unsigned char **value))
+{
+ unsigned char *value;
+ unsigned int count;
+ bool ret;
+
+ INF("BEGIN: testing ushort get %s of element %s...\n", name, element->path);
+ ret = func(element, &count, &value);
+ if (ret)
+ {
+ INF("SUCCESS: testing ushort get %s of element %s: %p\n",
+ name, element->path, value);
+ free(value);
+ }
+ else
+ WRN("FAILURE: testing ushort get %s of element %s\n",
+ name, element->path);
+
+ return ret;
+}
+
+static bool
+_test_element_get(E_Connman_Element *element, const char *name, bool (*func)(const E_Connman_Element *element, E_Connman_Element **value))
+{
+ E_Connman_Element *value;
+ bool ret;
+
+ INF("BEGIN: testing element get %s of element %s...\n", name, element->path);
+ ret = func(element, &value);
+ if (ret)
+ INF("SUCCESS: testing element get %s of element %s: %p\n",
+ name, element->path, value);
+ else
+ WRN("FAILURE: testing element get %s of element %s\n",
+ name, element->path);
+
+ return ret;
+}
+
+static bool
+_test_elements_get(E_Connman_Element *element, const char *name, bool (*func)(const E_Connman_Element *element, unsigned int *count, E_Connman_Element ***elements))
+{
+ E_Connman_Element **value;
+ unsigned int count;
+ bool ret;
+
+ INF("BEGIN: testing elements get %s of element %s...\n",
+ name, element->path);
+ ret = func(element, &count, &value);
+ if (ret)
+ {
+ INF("SUCCESS: testing elements get %s of element %s: %p\n",
+ name, element->path, value);
+ free(value);
+ }
+ else
+ WRN("FAILURE: testing elements get %s of element %s\n",
+ name, element->path);
+
+ return ret;
+}
+
+static bool
+_test_elements_get_global(const char *name, bool (*func)(unsigned int *count, E_Connman_Element ***elements))
+{
+ E_Connman_Element **value;
+ unsigned int count;
+ bool ret;
+
+ INF("BEGIN: testing elements get %s\n", name);
+ ret = func(&count, &value);
+ if (ret)
+ {
+ INF("SUCCESS: testing elements get %s: %p\n", name, value);
+ free(value);
+ }
+ else
+ WRN("FAILURE: testing elements get %s\n", name);
+
+ return ret;
+}
+
+static bool
+_test_string_get_global(const char *name, bool (*func)(const char **value))
+{
+ const char *value;
+ bool ret;
+
+ INF("BEGIN: testing string get %s...\n", name);
+ ret = func(&value);
+ if (ret)
+ INF("SUCCESS: testing string get %s: %s\n", name, value);
+ else
+ WRN("FAILURE: testing string get %s\n", name);
+
+ return ret;
+}
+
+static bool
+_test_bool_get_global(const char *name, bool (*func)(bool *value))
+{
+ bool value, ret;
+
+ INF("BEGIN: testing bool get %s...\n", name);
+ ret = func(&value);
+ if (ret)
+ INF("SUCCESS: testing bool get %s: %hhu\n", name, value);
+ else
+ WRN("FAILURE: testing bool get %s\n", name);
+
+ return ret;
+}
+
+struct test_desc
+{
+ const char *name;
+ enum {
+ TEST_DESC_TYPE_STRING_GET,
+ TEST_DESC_TYPE_BOOL_GET,
+ TEST_DESC_TYPE_UCHAR_GET,
+ TEST_DESC_TYPE_USHORT_GET,
+ TEST_DESC_TYPE_UCHAR_ARRAY_GET,
+ TEST_DESC_TYPE_ELEMENT_GET,
+ TEST_DESC_TYPE_ELEMENTS_GET,
+ TEST_DESC_TYPE_ELEMENTS_GET_GLOBAL,
+ TEST_DESC_TYPE_STRING_GET_GLOBAL,
+ TEST_DESC_TYPE_BOOL_GET_GLOBAL,
+ TEST_DESC_TYPE_LAST
+ } type;
+ union {
+ bool (*string_get)(const E_Connman_Element *element, const char **value);
+ bool (*bool_get)(const E_Connman_Element *element, bool *value);
+ bool (*uchar_get)(const E_Connman_Element *element, unsigned char *value);
+ bool (*ushort_get)(const E_Connman_Element *element, unsigned short*value);
+ bool (*uchar_array_get)(const E_Connman_Element *element, unsigned int *count, unsigned char **value);
+ bool (*element_get)(const E_Connman_Element *element, E_Connman_Element **value);
+ bool (*elements_get)(const E_Connman_Element *element, unsigned int *count, E_Connman_Element ***elements);
+ bool (*elements_get_global)(unsigned int *count, E_Connman_Element ***elements);
+ bool (*string_get_global)(const char **value);
+ bool (*bool_get_global)(bool *value);
+ void *dummy;
+ } func;
+ bool may_fail;
+};
+
+#define TEST_DESC_STRING_GET(_func, may_fail) \
+ {#_func, TEST_DESC_TYPE_STRING_GET, .func.string_get=_func, may_fail}
+#define TEST_DESC_BOOL_GET(_func, may_fail) \
+ {#_func, TEST_DESC_TYPE_BOOL_GET, .func.bool_get=_func, may_fail}
+#define TEST_DESC_UCHAR_GET(_func, may_fail) \
+ {#_func, TEST_DESC_TYPE_UCHAR_GET, .func.uchar_get=_func, may_fail}
+#define TEST_DESC_USHORT_GET(_func, may_fail) \
+ {#_func, TEST_DESC_TYPE_USHORT_GET, .func.ushort_get=_func, may_fail}
+#define TEST_DESC_UCHAR_ARRAY_GET(_func, may_fail) \
+ {#_func, TEST_DESC_TYPE_UCHAR_ARRAY_GET, .func.uchar_array_get=_func, may_fail}
+#define TEST_DESC_ELEMENT_GET(_func, may_fail) \
+ {#_func, TEST_DESC_TYPE_ELEMENT_GET, .func.element_get=_func, may_fail}
+#define TEST_DESC_ELEMENTS_GET(_func, may_fail) \
+ {#_func, TEST_DESC_TYPE_ELEMENTS_GET, .func.elements_get=_func, may_fail}
+#define TEST_DESC_ELEMENTS_GET_GLOBAL(_func, may_fail) \
+ {#_func, TEST_DESC_TYPE_ELEMENTS_GET_GLOBAL, .func.elements_get_global=_func, may_fail}
+#define TEST_DESC_STRING_GET_GLOBAL(_func, may_fail) \
+ {#_func, TEST_DESC_TYPE_STRING_GET_GLOBAL, .func.string_get_global=_func, may_fail}
+#define TEST_DESC_BOOL_GET_GLOBAL(_func, may_fail) \
+ {#_func, TEST_DESC_TYPE_BOOL_GET_GLOBAL, .func.bool_get_global=_func, may_fail}
+#define TEST_DESC_SENTINEL {NULL, TEST_DESC_TYPE_LAST, .func.dummy=NULL}
+
+static bool
+_test_element(E_Connman_Element *element, const struct test_desc *test_descs)
+{
+ const struct test_desc *itr;
+ int total, ok = 0, fail = 0;
+ bool ret = 1;
+
+ for (itr = test_descs; itr->type != TEST_DESC_TYPE_LAST; itr++)
+ {
+ bool r;
+
+ switch (itr->type)
+ {
+ case TEST_DESC_TYPE_STRING_GET:
+ r = _test_string_get(element, itr->name, itr->func.string_get);
+ break;
+ case TEST_DESC_TYPE_BOOL_GET:
+ r = _test_bool_get(element, itr->name, itr->func.bool_get);
+ break;
+ case TEST_DESC_TYPE_UCHAR_GET:
+ r = _test_uchar_get(element, itr->name, itr->func.uchar_get);
+ break;
+ case TEST_DESC_TYPE_USHORT_GET:
+ r = _test_ushort_get(element, itr->name, itr->func.ushort_get);
+ break;
+ case TEST_DESC_TYPE_UCHAR_ARRAY_GET:
+ r = _test_uchar_array_get
+ (element, itr->name, itr->func.uchar_array_get);
+ break;
+ case TEST_DESC_TYPE_ELEMENT_GET:
+ r = _test_element_get
+ (element, itr->name, itr->func.element_get);
+ break;
+ case TEST_DESC_TYPE_ELEMENTS_GET:
+ r = _test_elements_get
+ (element, itr->name, itr->func.elements_get);
+ break;
+ case TEST_DESC_TYPE_ELEMENTS_GET_GLOBAL:
+ r = _test_elements_get_global
+ (itr->name, itr->func.elements_get_global);
+ break;
+ case TEST_DESC_TYPE_STRING_GET_GLOBAL:
+ r = _test_string_get_global
+ (itr->name, itr->func.string_get_global);
+ break;
+ case TEST_DESC_TYPE_BOOL_GET_GLOBAL:
+ r = _test_bool_get_global
+ (itr->name, itr->func.bool_get_global);
+ break;
+ default:
+ ERR("unknown test type %d (%s)\n", itr->type, itr->name);
+ r = 0;
+ break;
+ }
+
+ if (r || itr->may_fail)
+ ok++;
+ else
+ {
+ ERR("test failed %s, element %s [%s]\n",
+ itr->name, element->path, element->interface);
+ fail++;
+ ret = 0;
+ }
+ }
+
+ total = ok + failure;
+ success += ok;
+ failure += fail;
+ if (total == 0)
+ {
+ INF("no tests for %s [%s]\n", element->path, element->interface);
+ return 1;
+ }
+
+ INF("testing %s success: %d, failure: %d: %d%% [%s]\n",
+ element->path, ok, fail, (ok * 100) / total,
+ element->interface);
+
+ return ret;
+}
+
+static const struct test_desc test_desc_manager[] = {
+ TEST_DESC_STRING_GET_GLOBAL(e_connman_manager_state_get, 0),
+ TEST_DESC_STRING_GET_GLOBAL(e_connman_manager_policy_get, 0),
+ //TEST_DESC_STRING_SET_GLOBAL(e_connman_manager_policy_set, 0),
+ TEST_DESC_BOOL_GET_GLOBAL(e_connman_manager_offline_mode_get, 0),
+ //TEST_DESC_BOOL_SET_GLOBAL(e_connman_manager_offline_mode_set, 0),
+ TEST_DESC_ELEMENTS_GET_GLOBAL(e_connman_manager_profiles_get, 0),
+ TEST_DESC_ELEMENTS_GET_GLOBAL(e_connman_manager_devices_get, 0),
+ TEST_DESC_ELEMENTS_GET_GLOBAL(e_connman_manager_connections_get, 1),
+ TEST_DESC_SENTINEL
+};
+
+static const struct test_desc test_desc_device[] = {
+ TEST_DESC_STRING_GET(e_connman_device_name_get, 0),
+ TEST_DESC_STRING_GET(e_connman_device_type_get, 0),
+ TEST_DESC_STRING_GET(e_connman_device_interface_get, 0),
+ TEST_DESC_STRING_GET(e_connman_device_policy_get, 0),
+ //TEST_DESC_STRING_SET(e_connman_device_policy_set, 0),
+ TEST_DESC_UCHAR_GET(e_connman_device_priority_get, 0),
+ //TEST_DESC_UCHAR_SET(e_connman_device_priority_set, 0),
+ TEST_DESC_BOOL_GET(e_connman_device_powered_get, 0),
+ //TEST_DESC_BOOL_SET(e_connman_device_powered_set, 0),
+ TEST_DESC_USHORT_GET(e_connman_device_scan_interval_get, 1),
+ //TEST_DESC_USHORT_SET(e_connman_device_scan_interval_set, 1),
+ TEST_DESC_BOOL_GET(e_connman_device_scanning_get, 1),
+ TEST_DESC_ELEMENTS_GET(e_connman_device_networks_get, 1),
+ TEST_DESC_SENTINEL
+};
+
+static const struct test_desc test_desc_profile[] = {
+ TEST_DESC_STRING_GET(e_connman_profile_name_get, 0),
+ TEST_DESC_SENTINEL
+};
+
+static const struct test_desc test_desc_connection[] = {
+ TEST_DESC_STRING_GET(e_connman_connection_type_get, 0),
+ TEST_DESC_STRING_GET(e_connman_connection_interface_get, 0),
+ TEST_DESC_UCHAR_GET(e_connman_connection_strength_get, 0),
+ TEST_DESC_BOOL_GET(e_connman_connection_default_get, 0),
+ TEST_DESC_ELEMENT_GET(e_connman_connection_device_get, 0),
+ TEST_DESC_ELEMENT_GET(e_connman_connection_network_get, 0),
+ TEST_DESC_STRING_GET(e_connman_connection_ipv4_method_get, 0),
+ TEST_DESC_STRING_GET(e_connman_connection_ipv4_address_get, 0),
+ TEST_DESC_SENTINEL
+};
+
+static const struct test_desc test_desc_network[] = {
+ TEST_DESC_STRING_GET(e_connman_network_name_get, 0),
+ TEST_DESC_BOOL_GET(e_connman_network_available_get, 0),
+ TEST_DESC_BOOL_GET(e_connman_network_connected_get, 0),
+ TEST_DESC_BOOL_GET(e_connman_network_remember_get, 0),
+ //TEST_DESC_BOOL_SET(e_connman_network_remember_set, 0),
+ TEST_DESC_UCHAR_GET(e_connman_network_strength_get, 1),
+ TEST_DESC_ELEMENT_GET(e_connman_network_device_get, 0),
+ TEST_DESC_UCHAR_ARRAY_GET(e_connman_network_wifi_ssid_get, 1),
+ TEST_DESC_STRING_GET(e_connman_network_wifi_mode_get, 1),
+ // TEST_DESC_STRING_SET(e_connman_network_wifi_mode_set, 1),
+ TEST_DESC_STRING_GET(e_connman_network_wifi_security_get, 1),
+ // TEST_DESC_STRING_SET(e_connman_network_wifi_security_set, 1),
+ TEST_DESC_STRING_GET(e_connman_network_wifi_passphrase_get, 1),
+ //TEST_DESC_STRING_SET(e_connman_network_wifi_passphrase_set, 1),
+ TEST_DESC_SENTINEL
+};
+
+static int
+_quit(void *data)
+{
+ ecore_main_loop_quit();
+ return 0;
+}
+
+static int
+_on_exiter(void *data)
+{
+ e_connman_system_shutdown();
+ ecore_idle_enterer_add(_quit, NULL);
+ exiter = NULL;
+ return 0;
+}
+
+static void
+_exiter_reschedule(void)
+{
+ if (exiter)
+ ecore_timer_del(exiter);
+ exiter = ecore_timer_add(10, _on_exiter, NULL);
+}
+
+struct test_element_timer_data
+{
+ E_Connman_Element *element;
+ Ecore_Timer *timer;
+};
+
+static int
+_test_element_timer(void *data)
+{
+ struct test_element_timer_data *d = data;
+ E_Connman_Element *element = d->element;
+
+ if (e_connman_element_is_device(element))
+ _test_element(element, test_desc_device);
+ else if (e_connman_element_is_profile(element))
+ _test_element(element, test_desc_profile);
+ else if (e_connman_element_is_connection(element))
+ _test_element(element, test_desc_connection);
+ else if (e_connman_element_is_network(element))
+ _test_element(element, test_desc_network);
+ else if (e_connman_element_is_manager(element))
+ _test_element(element, test_desc_manager);
+ else
+ ERR("!!! don't know how to test %s [%s]\n",
+ element->path, element->interface);
+
+ _exiter_reschedule();
+
+ d->timer = NULL;
+ return 0;
+}
+
+static void
+_element_listener(void *data, const E_Connman_Element *element)
+{
+ struct test_element_timer_data *d = data;
+ if (d->timer)
+ ecore_timer_del(d->timer);
+ d->timer = ecore_timer_add(1.0, _test_element_timer, d);
+ _exiter_reschedule();
+}
+
+static void
+_element_listener_free(void *data)
+{
+ struct test_element_timer_data *d = data;
+ if (d->timer)
+ ecore_timer_del(d->timer);
+ free(d);
+}
+
+static int
+_on_element_add(void *data, int type, void *info)
+{
+ E_Connman_Element *element = info;
+ struct test_element_timer_data *d;
+
+ d = malloc(sizeof(*d));
+ if (!d)
+ return 1;
+
+ d->element = element;
+ d->timer = ecore_timer_add(1.0, _test_element_timer, d);
+ e_connman_element_listener_add
+ (element, _element_listener, d, _element_listener_free);
+
+ return 1;
+}
+
+static int
+_on_element_del(void *data, int type, void *info)
+{
+ return 1;
+}
+
+static int
+_on_element_updated(void *data, int type, void *info)
+{
+ return 1;
+}
+
+int
+main(int argc, char *argv[])
+{
+ E_DBus_Connection *c;
+ int total;
+
+ ecore_init();
+ e_dbus_init();
+ eina_init();
+
+ c = e_dbus_bus_get(DBUS_BUS_SYSTEM);
+ if (!c) {
+ printf("ERROR: can't connect to system session\n");
+ return -1;
+ }
+
+ e_connman_system_init(c);
+ ecore_event_handler_add(E_CONNMAN_EVENT_ELEMENT_ADD, _on_element_add, NULL);
+ ecore_event_handler_add(E_CONNMAN_EVENT_ELEMENT_DEL, _on_element_del, NULL);
+ ecore_event_handler_add(E_CONNMAN_EVENT_ELEMENT_UPDATED,
+ _on_element_updated, NULL);
+
+ _exiter_reschedule();
+
+ ecore_main_loop_begin();
+
+ e_dbus_connection_close(c);
+ eina_stringshare_dump();
+ eina_shutdown();
+ e_dbus_shutdown();
+ ecore_shutdown();
+
+ total = success + failure;
+ if (total == 0)
+ fputs("DBG: clean exit, no tests executed.\n", stderr);
+ else
+ fprintf(stderr, "DBG: clean exit, success: %d, failure: %d, %d%%\n",
+ success, failure, (success * 100) / total);
+
+ return 0;
+}
MAINTAINERCLEANFILES = Makefile.in
-SUBDIRS=dbus hal nm notification
+SUBDIRS=dbus hal nm notification connman
--- /dev/null
+#ifndef E_CONNMAN_H
+#define E_CONNMAN_H
+
+#include <E_DBus.h>
+#include <Ecore_Data.h>
+#include <stdint.h>
+#include <stdbool.h>
+#include <stdio.h>
+
+#ifdef EAPI
+#undef EAPI
+#endif
+#ifdef _MSC_VER
+# ifdef BUILDING_DLL
+# define EAPI __declspec(dllexport)
+# else
+# define EAPI __declspec(dllimport)
+# endif
+#else
+# ifdef __GNUC__
+# if __GNUC__ >= 4
+# define EAPI __attribute__ ((visibility("default")))
+# else
+# define EAPI
+# endif
+# else
+# define EAPI
+# endif
+#endif
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+ /* Ecore Events */
+ extern int E_CONNMAN_EVENT_MANAGER_IN;
+ extern int E_CONNMAN_EVENT_MANAGER_OUT;
+ extern int E_CONNMAN_EVENT_ELEMENT_ADD;
+ extern int E_CONNMAN_EVENT_ELEMENT_DEL;
+ extern int E_CONNMAN_EVENT_ELEMENT_UPDATED;
+
+ typedef struct _E_Connman_Element E_Connman_Element;
+
+ struct _E_Connman_Element
+ {
+ const char *path;
+ const char *interface;
+ E_DBus_Signal_Handler *signal_handler;
+ Eina_Inlist *props;
+
+ /* private */
+ struct {
+ Eina_Inlist *properties_get;
+ Eina_Inlist *property_set;
+ Eina_Inlist *network_create;
+ Eina_Inlist *network_remove;
+ Eina_Inlist *network_connect;
+ Eina_Inlist *network_disconnect;
+ Eina_Inlist *agent_register;
+ Eina_Inlist *agent_unregister;
+ Eina_Inlist *device_propose_scan;
+ } _pending;
+ struct {
+ Ecore_Idler *changed;
+ } _idler;
+ Eina_Inlist *_listeners;
+ int _references;
+ };
+
+ EAPI unsigned int e_connman_system_init(E_DBus_Connection *edbus_conn) EINA_ARG_NONNULL(1);
+ EAPI unsigned int e_connman_system_shutdown(void);
+
+ EAPI bool e_connman_manager_sync_elements(void);
+
+ EAPI bool e_connman_elements_get_all(unsigned int *count, E_Connman_Element ***p_elements) EINA_ARG_NONNULL(1, 2) EINA_PURE EINA_WARN_UNUSED_RESULT;
+ EAPI bool e_connman_elements_get_all_type(const char *type, unsigned int *count, E_Connman_Element ***p_elements) EINA_ARG_NONNULL(1, 2, 3) EINA_PURE EINA_WARN_UNUSED_RESULT;
+ EAPI E_Connman_Element *e_connman_element_get(const char *path);
+
+ EAPI void e_connman_element_listener_add(E_Connman_Element *element, void (*cb)(void *data, const E_Connman_Element *element), const void *data, void (*free_data)(void *data)) EINA_ARG_NONNULL(1, 2);
+ EAPI void e_connman_element_listener_del(E_Connman_Element *element, void (*cb)(void *data, const E_Connman_Element *element), const void *data) EINA_ARG_NONNULL(1, 2);
+
+ EAPI int e_connman_element_ref(E_Connman_Element *element) EINA_ARG_NONNULL(1);
+ EAPI int e_connman_element_unref(E_Connman_Element *element) EINA_ARG_NONNULL(1);
+
+ EAPI void e_connman_element_print(FILE *fp, const E_Connman_Element *element) EINA_ARG_NONNULL(1, 2);
+
+
+ EAPI bool e_connman_element_properties_sync(E_Connman_Element *element) EINA_ARG_NONNULL(1);
+ EAPI bool e_connman_element_properties_sync_full(E_Connman_Element *element, E_DBus_Method_Return_Cb cb, const void *data) EINA_ARG_NONNULL(1);
+
+ EAPI bool e_connman_element_property_set(E_Connman_Element *element, const char *prop, int type, const void *value) EINA_ARG_NONNULL(1, 2) EINA_WARN_UNUSED_RESULT;
+ EAPI bool e_connman_element_property_set_full(E_Connman_Element *element, const char *prop, int type, const void *value, E_DBus_Method_Return_Cb cb, const void *data) EINA_ARG_NONNULL(1, 2) EINA_WARN_UNUSED_RESULT;
+
+ EAPI void e_connman_element_properties_list(const E_Connman_Element *element, bool (*cb)(void *data, const E_Connman_Element *element, const char *name, int type, const void *value), const void *data) EINA_ARG_NONNULL(1, 2);
+
+ EAPI bool e_connman_element_property_type_get_stringshared(const E_Connman_Element *element, const char *name, int *type) EINA_ARG_NONNULL(1, 2, 3) EINA_PURE EINA_WARN_UNUSED_RESULT;
+ EAPI bool e_connman_element_property_type_get(const E_Connman_Element *element, const char *name, int *type) EINA_ARG_NONNULL(1, 2, 3) EINA_PURE EINA_WARN_UNUSED_RESULT;
+ EAPI bool e_connman_element_property_get_stringshared(const E_Connman_Element *element, const char *name, int *type, void *value) EINA_ARG_NONNULL(1, 2, 4) EINA_PURE EINA_WARN_UNUSED_RESULT;
+ EAPI bool e_connman_element_property_get(const E_Connman_Element *element, const char *name, int *type, void *value) EINA_ARG_NONNULL(1, 2, 4) EINA_PURE EINA_WARN_UNUSED_RESULT;
+
+ EAPI bool e_connman_element_is_manager(const E_Connman_Element *element) EINA_ARG_NONNULL(1) EINA_PURE EINA_WARN_UNUSED_RESULT;
+ EAPI bool e_connman_element_is_device(const E_Connman_Element *element) EINA_ARG_NONNULL(1) EINA_PURE EINA_WARN_UNUSED_RESULT;
+ EAPI bool e_connman_element_is_profile(const E_Connman_Element *element) EINA_ARG_NONNULL(1) EINA_PURE EINA_WARN_UNUSED_RESULT;
+ EAPI bool e_connman_element_is_connection(const E_Connman_Element *element) EINA_ARG_NONNULL(1) EINA_PURE EINA_WARN_UNUSED_RESULT;
+ EAPI bool e_connman_element_is_network(const E_Connman_Element *element) EINA_ARG_NONNULL(1) EINA_PURE EINA_WARN_UNUSED_RESULT;
+
+
+ /* Manager Methods */
+
+ EAPI E_Connman_Element *e_connman_manager_get(void) EINA_ARG_NONNULL(1) EINA_PURE EINA_WARN_UNUSED_RESULT;
+
+ EAPI bool e_connman_manager_register_agent(const char *object_path, E_DBus_Method_Return_Cb cb, const void *data);
+ EAPI bool e_connman_manager_unregister_agent(const char *object_path, E_DBus_Method_Return_Cb cb, const void *data);
+
+ EAPI bool e_connman_manager_state_get(const char **state);
+
+ EAPI bool e_connman_manager_policy_get(const char **policy);
+ EAPI bool e_connman_manager_policy_set(const char *policy, E_DBus_Method_Return_Cb cb, const void *data);
+
+ EAPI bool e_connman_manager_offline_mode_get(bool *offline);
+ EAPI bool e_connman_manager_offline_mode_set(bool offline, E_DBus_Method_Return_Cb cb, const void *data);
+
+ EAPI bool e_connman_manager_profiles_get(unsigned int *count, E_Connman_Element ***p_elements);
+ EAPI bool e_connman_manager_devices_get(unsigned int *count, E_Connman_Element ***p_elements);
+ EAPI bool e_connman_manager_connections_get(unsigned int *count, E_Connman_Element ***p_elements);
+
+ // TODO: profile_add (not implemented in connman right now)
+ // TODO: profile_remove (not implemented in connman right now)
+ // TODO: profile_active_get (not implemented in connman right now)
+ // TODO: profile_active_set (not implemented in connman right now)
+ // TODO: services_get (not implemented in connman right now)
+
+
+ /* Device Methods */
+ EAPI E_Connman_Element *e_connman_device_get(const char *path) EINA_ARG_NONNULL(1) EINA_PURE EINA_WARN_UNUSED_RESULT;
+
+ EAPI bool e_connman_device_network_create(E_Connman_Element *device, E_DBus_Method_Return_Cb cb, const void *data) EINA_ARG_NONNULL(1) EINA_WARN_UNUSED_RESULT;
+ EAPI bool e_connman_device_network_remove(E_Connman_Element *device, const char *network_path, E_DBus_Method_Return_Cb cb, const void *data) EINA_ARG_NONNULL(1, 2) EINA_WARN_UNUSED_RESULT;
+
+ EAPI bool e_connman_device_propose_scan(E_Connman_Element *device, E_DBus_Method_Return_Cb cb, const void *data) EINA_ARG_NONNULL(1) EINA_WARN_UNUSED_RESULT;
+
+ EAPI bool e_connman_device_name_get(const E_Connman_Element *device, const char **name) EINA_ARG_NONNULL(1, 2) EINA_PURE EINA_WARN_UNUSED_RESULT;
+
+ EAPI bool e_connman_device_type_get(const E_Connman_Element *device, const char **type) EINA_ARG_NONNULL(1, 2) EINA_PURE EINA_WARN_UNUSED_RESULT;
+
+ EAPI bool e_connman_device_interface_get(const E_Connman_Element *device, const char **interface) EINA_ARG_NONNULL(1, 2) EINA_PURE EINA_WARN_UNUSED_RESULT;
+
+ EAPI bool e_connman_device_policy_get(const E_Connman_Element *device, const char **policy) EINA_ARG_NONNULL(1, 2) EINA_PURE EINA_WARN_UNUSED_RESULT;
+ EAPI bool e_connman_device_policy_set(E_Connman_Element *device, const char *policy, E_DBus_Method_Return_Cb cb, const void *data) EINA_ARG_NONNULL(1, 2) EINA_WARN_UNUSED_RESULT;
+
+ EAPI bool e_connman_device_priority_get(const E_Connman_Element *device, unsigned char *priority) EINA_ARG_NONNULL(1, 2) EINA_PURE EINA_WARN_UNUSED_RESULT;
+ EAPI bool e_connman_device_priority_set(E_Connman_Element *device, unsigned char priority, E_DBus_Method_Return_Cb cb, const void *data) EINA_ARG_NONNULL(1) EINA_WARN_UNUSED_RESULT;
+
+ EAPI bool e_connman_device_powered_get(const E_Connman_Element *device, bool *powered) EINA_ARG_NONNULL(1, 2) EINA_PURE EINA_WARN_UNUSED_RESULT;
+ EAPI bool e_connman_device_powered_set(E_Connman_Element *device, bool powered, E_DBus_Method_Return_Cb cb, const void *data) EINA_ARG_NONNULL(1) EINA_WARN_UNUSED_RESULT;
+
+ EAPI bool e_connman_device_scan_interval_get(const E_Connman_Element *device, unsigned short *scan_interval) EINA_ARG_NONNULL(1, 2) EINA_PURE EINA_WARN_UNUSED_RESULT;
+ EAPI bool e_connman_device_scan_interval_set(E_Connman_Element *device, unsigned short scan_interval, E_DBus_Method_Return_Cb cb, const void *data) EINA_ARG_NONNULL(1) EINA_WARN_UNUSED_RESULT;
+
+ EAPI bool e_connman_device_scanning_get(const E_Connman_Element *device, bool *scanning) EINA_ARG_NONNULL(1, 2) EINA_PURE EINA_WARN_UNUSED_RESULT;
+
+ EAPI bool e_connman_device_networks_get(const E_Connman_Element *device, unsigned int *count, E_Connman_Element ***p_elements) EINA_ARG_NONNULL(1, 2, 3) EINA_PURE EINA_WARN_UNUSED_RESULT;
+
+ // TODO: network_join (harder, need to think of good api that do not suck)
+ // TODO: address_get
+
+
+ /* Profile Methods */
+
+ EAPI E_Connman_Element *e_connman_profile_get(const char *path) EINA_ARG_NONNULL(1) EINA_PURE EINA_WARN_UNUSED_RESULT;
+ EAPI bool e_connman_profile_name_get(const E_Connman_Element *profile, const char **name) EINA_ARG_NONNULL(1, 2) EINA_PURE EINA_WARN_UNUSED_RESULT;
+
+ // TODO: services_get (not implemented in connman right now)
+
+ /* Connection Methods */
+
+ EAPI E_Connman_Element *e_connman_connection_get(const char *path) EINA_ARG_NONNULL(1) EINA_PURE EINA_WARN_UNUSED_RESULT;
+
+ EAPI bool e_connman_connection_type_get(const E_Connman_Element *connection, const char **type) EINA_ARG_NONNULL(1, 2) EINA_PURE EINA_WARN_UNUSED_RESULT;
+
+ EAPI bool e_connman_connection_interface_get(const E_Connman_Element *connection, const char **interface) EINA_ARG_NONNULL(1, 2) EINA_PURE EINA_WARN_UNUSED_RESULT;
+
+ EAPI bool e_connman_connection_strength_get(const E_Connman_Element *connection, unsigned char *strength) EINA_ARG_NONNULL(1, 2) EINA_PURE EINA_WARN_UNUSED_RESULT;
+
+ EAPI bool e_connman_connection_default_get(const E_Connman_Element *connection, bool *connection_default) EINA_ARG_NONNULL(1, 2) EINA_PURE EINA_WARN_UNUSED_RESULT;
+
+ EAPI bool e_connman_connection_device_get(const E_Connman_Element *connection, E_Connman_Element **element) EINA_ARG_NONNULL(1, 2) EINA_PURE EINA_WARN_UNUSED_RESULT;
+ EAPI bool e_connman_connection_network_get(const E_Connman_Element *connection, E_Connman_Element **element) EINA_ARG_NONNULL(1, 2) EINA_PURE EINA_WARN_UNUSED_RESULT;
+
+ EAPI bool e_connman_connection_ipv4_method_get(const E_Connman_Element *connection, const char **method) EINA_ARG_NONNULL(1, 2) EINA_PURE EINA_WARN_UNUSED_RESULT;
+ EAPI bool e_connman_connection_ipv4_address_get(const E_Connman_Element *connection, const char **address) EINA_ARG_NONNULL(1, 2) EINA_PURE EINA_WARN_UNUSED_RESULT;
+
+ // TODO: ipv4_gateway_get
+ // TODO: ipv4_netmask_get
+
+
+ /* Network Methods */
+ EAPI E_Connman_Element *e_connman_network_get(const char *path) EINA_ARG_NONNULL(1) EINA_PURE EINA_WARN_UNUSED_RESULT;
+
+ EAPI bool e_connman_network_connect(E_Connman_Element *network, E_DBus_Method_Return_Cb cb, const void *data) EINA_ARG_NONNULL(1) EINA_WARN_UNUSED_RESULT;
+ EAPI bool e_connman_network_disconnect(E_Connman_Element *network, E_DBus_Method_Return_Cb cb, const void *data) EINA_ARG_NONNULL(1) EINA_WARN_UNUSED_RESULT;
+
+ EAPI bool e_connman_network_name_get(const E_Connman_Element *network, const char **name) EINA_ARG_NONNULL(1, 2) EINA_PURE EINA_WARN_UNUSED_RESULT;
+
+ EAPI bool e_connman_network_available_get(const E_Connman_Element *network, bool *available) EINA_ARG_NONNULL(1, 2) EINA_PURE EINA_WARN_UNUSED_RESULT;
+
+ EAPI bool e_connman_network_connected_get(const E_Connman_Element *network, bool *connected) EINA_ARG_NONNULL(1, 2) EINA_PURE EINA_WARN_UNUSED_RESULT;
+
+ EAPI bool e_connman_network_remember_get(const E_Connman_Element *network, bool *remember) EINA_ARG_NONNULL(1, 2) EINA_PURE EINA_WARN_UNUSED_RESULT;
+ EAPI bool e_connman_network_remember_set(E_Connman_Element *network, bool remember, E_DBus_Method_Return_Cb cb, const void *data) EINA_ARG_NONNULL(1) EINA_WARN_UNUSED_RESULT;
+
+ EAPI bool e_connman_network_strength_get(const E_Connman_Element *network, unsigned char *strength) EINA_ARG_NONNULL(1, 2) EINA_PURE EINA_WARN_UNUSED_RESULT;
+
+ EAPI bool e_connman_network_device_get(const E_Connman_Element *network, E_Connman_Element **element) EINA_ARG_NONNULL(1, 2) EINA_PURE EINA_WARN_UNUSED_RESULT;
+
+ EAPI bool e_connman_network_wifi_ssid_get(const E_Connman_Element *network, unsigned int *count, unsigned char **wifi_ssid) EINA_ARG_NONNULL(1, 2, 3) EINA_PURE EINA_WARN_UNUSED_RESULT;
+
+ EAPI bool e_connman_network_wifi_mode_get(const E_Connman_Element *network, const char **wifi_mode) EINA_ARG_NONNULL(1, 2) EINA_PURE EINA_WARN_UNUSED_RESULT;
+ EAPI bool e_connman_network_wifi_mode_set(E_Connman_Element *network, const char *wifi_mode, E_DBus_Method_Return_Cb cb, const void *data) EINA_ARG_NONNULL(1) EINA_WARN_UNUSED_RESULT;
+
+ EAPI bool e_connman_network_wifi_security_get(const E_Connman_Element *network, const char **wifi_security) EINA_ARG_NONNULL(1, 2) EINA_PURE EINA_WARN_UNUSED_RESULT;
+ EAPI bool e_connman_network_wifi_security_set(E_Connman_Element *network, const char *wifi_security, E_DBus_Method_Return_Cb cb, const void *data) EINA_ARG_NONNULL(1) EINA_WARN_UNUSED_RESULT;
+
+ EAPI bool e_connman_network_wifi_passphrase_get(const E_Connman_Element *network, const char **wifi_passphare) EINA_ARG_NONNULL(1, 2) EINA_PURE EINA_WARN_UNUSED_RESULT;
+ EAPI bool e_connman_network_wifi_passphrase_set(E_Connman_Element *network, const char *wifi_passphrase, E_DBus_Method_Return_Cb cb, const void *data) EINA_ARG_NONNULL(1) EINA_WARN_UNUSED_RESULT;
+
+ // TODO: address_get
+
+#ifdef __cplusplus
+}
+#endif
+#endif /* E_CONNMAN_H */
--- /dev/null
+MAINTAINERCLEANFILES = Makefile.in
+
+AM_CPPFLAGS = \
+-I $(top_srcdir)/src/lib/dbus \
+@EDBUS_CFLAGS@ @EVAS_CFLAGS@ @EINA_CFLAGS@
+
+if BUILD_ECONNMAN
+
+lib_LTLIBRARIES = libeconnman.la
+include_HEADERS = E_Connman.h
+
+libeconnman_la_SOURCES = \
+E_Connman.h \
+e_connman_private.h \
+e_connman.c \
+e_connman_connection.c \
+e_connman_device.c \
+e_connman_element.c \
+e_connman_manager.c \
+e_connman_network.c \
+e_connman_profile.c
+
+libeconnman_la_LIBADD = \
+@EDBUS_LIBS@ @EVAS_LIBS@ \
+$(top_builddir)/src/lib/dbus/libedbus.la \
+@EINA_LIBS@
+
+libeconnman_la_LDFLAGS = -version-info @version_info@
+
+endif
--- /dev/null
+#include "e_connman_private.h"
+#include <stdlib.h>
+#include <string.h>
+
+static E_DBus_Signal_Handler *cb_name_owner_changed = NULL;
+static DBusPendingCall *pending_get_name_owner = NULL;
+static unsigned int init_count = 0;
+static char *unique_name = NULL;
+
+static const char bus_name[] = "org.moblin.connman";
+static const char fdo_bus_name[] = "org.freedesktop.DBus";
+static const char fdo_interface[] = "org.freedesktop.DBus";
+static const char fdo_path[] = "/org/freedesktop/DBus";
+
+E_DBus_Connection *e_connman_conn = NULL;
+
+EAPI int E_CONNMAN_EVENT_MANAGER_IN = 0;
+EAPI int E_CONNMAN_EVENT_MANAGER_OUT = 0;
+EAPI int E_CONNMAN_EVENT_ELEMENT_ADD = 0;
+EAPI int E_CONNMAN_EVENT_ELEMENT_DEL = 0;
+EAPI int E_CONNMAN_EVENT_ELEMENT_UPDATED = 0;
+
+const char *e_connman_iface_manager = NULL;
+const char *e_connman_iface_network = NULL;
+const char *e_connman_iface_profile = NULL;
+const char *e_connman_iface_service = NULL;
+const char *e_connman_iface_device = NULL;
+const char *e_connman_iface_connection = NULL;
+
+const char *e_connman_prop_available = NULL;
+const char *e_connman_prop_connected = NULL;
+const char *e_connman_prop_connections = NULL;
+const char *e_connman_prop_default = NULL;
+const char *e_connman_prop_device = NULL;
+const char *e_connman_prop_devices = NULL;
+const char *e_connman_prop_interface = NULL;
+const char *e_connman_prop_ipv4_address = NULL;
+const char *e_connman_prop_ipv4_method = NULL;
+const char *e_connman_prop_name = NULL;
+const char *e_connman_prop_network = NULL;
+const char *e_connman_prop_networks = NULL;
+const char *e_connman_prop_offline_mode = NULL;
+const char *e_connman_prop_policy = NULL;
+const char *e_connman_prop_powered = NULL;
+const char *e_connman_prop_priority = NULL;
+const char *e_connman_prop_profiles = NULL;
+const char *e_connman_prop_remember = NULL;
+const char *e_connman_prop_scan_interval = NULL;
+const char *e_connman_prop_scanning = NULL;
+const char *e_connman_prop_state = NULL;
+const char *e_connman_prop_strengh = NULL;
+const char *e_connman_prop_type = NULL;
+const char *e_connman_prop_wifi_mode = NULL;
+const char *e_connman_prop_wifi_passphrase = NULL;
+const char *e_connman_prop_wifi_security = NULL;
+const char *e_connman_prop_wifi_ssid = NULL;
+
+const char *
+e_connman_system_bus_name_get(void)
+{
+ return unique_name ? unique_name : bus_name;
+}
+
+
+/***********************************************************************
+ * Manager
+ ***********************************************************************/
+
+/**
+ * Synchronize elements with server.
+ *
+ * This will call Manager.GetProperties() on server, retrieve properties
+ * and some element paths and then request their properties.
+ *
+ * This call will add events E_CONNMAN_EVENT_ELEMENT_ADD and
+ * E_CONNMAN_EVENT_ELEMENT_UPDATED to the main loop.
+ *
+ * This will not remove stale elements.
+ *
+ * @return 1 on success, 0 otherwise.
+ */
+bool
+e_connman_manager_sync_elements(void)
+{
+ E_Connman_Element *manager;
+
+ if (!unique_name)
+ return FALSE;
+ manager = e_connman_element_register(manager_path, e_connman_iface_manager);
+ if (manager)
+ e_connman_element_properties_sync(manager);
+ else
+ return FALSE;
+
+ DBG("sync_manager: %s (%s)\n", unique_name, bus_name);
+
+ return TRUE;
+}
+
+static void
+_e_connman_system_name_owner_exit(void)
+{
+ e_connman_manager_clear_elements();
+ ecore_event_add(E_CONNMAN_EVENT_MANAGER_OUT, NULL, NULL, NULL);
+
+ free(unique_name);
+ unique_name = NULL;
+}
+
+static void
+_e_connman_system_name_owner_enter(const char *uid)
+{
+ DBG("enter connman at %s (old was %s)\n", uid, unique_name);
+ if (unique_name && strcmp(unique_name, uid) == 0)
+ {
+ DBG("same unique_name for connman, ignore.\n");
+ return;
+ }
+
+ if (unique_name)
+ _e_connman_system_name_owner_exit();
+
+ unique_name = strdup(uid);
+
+ ecore_event_add(E_CONNMAN_EVENT_MANAGER_IN, NULL, NULL, NULL);
+ e_connman_manager_sync_elements();
+}
+
+static void
+_e_connman_system_name_owner_changed(void *data, DBusMessage *msg)
+{
+ DBusError err;
+ const char *name, *from, *to;
+
+ dbus_error_init(&err);
+ if (!dbus_message_get_args(msg, &err,
+ DBUS_TYPE_STRING, &name,
+ DBUS_TYPE_STRING, &from,
+ DBUS_TYPE_STRING, &to,
+ DBUS_TYPE_INVALID))
+ {
+ ERR("could not get NameOwnerChanged arguments: %s: %s\n",
+ err.name, err.message);
+ dbus_error_free(&err);
+ return;
+ }
+
+ if (strcmp(name, bus_name) != 0)
+ return;
+
+ DBG("NameOwnerChanged from=[%s] to=[%s]\n", from, to);
+
+ if (from[0] == '\0' && to[0] != '\0')
+ _e_connman_system_name_owner_enter(to);
+ else if (from[0] != '\0' && to[0] == '\0')
+ {
+ DBG("exit connman at %s\n", from);
+ if (strcmp(unique_name, from) != 0)
+ DBG("%s was not the known name %s, ignored.\n", from, unique_name);
+ else
+ _e_connman_system_name_owner_exit();
+ }
+ else
+ DBG("unknow change from %s to %s\n", from, to);
+}
+
+static void
+_e_connman_get_name_owner(void *data, DBusMessage *msg, DBusError *err)
+{
+ DBusMessageIter itr;
+ int t;
+ const char *uid;
+
+ pending_get_name_owner = NULL;
+
+ if (!_dbus_callback_check_and_init(msg, &itr, err))
+ return;
+
+ t = dbus_message_iter_get_arg_type(&itr);
+ if (!_dbus_iter_type_check(t, DBUS_TYPE_STRING))
+ return;
+
+ dbus_message_iter_get_basic(&itr, &uid);
+ if (!uid)
+ {
+ ERR("no name owner!\n");
+ return;
+ }
+
+ _e_connman_system_name_owner_enter(uid);
+ return;
+}
+
+/**
+ * Initialize E Connection Manager (E_Connman) system.
+ *
+ * This will connect and watch org.moblin.connman.Manager and Element
+ * events and translate to Ecore main loop events, also provide a
+ * proxy for method invocation on server.
+ *
+ * Interesting events are:
+ * - E_CONNMAN_EVENT_MANAGER_IN: issued when connman is avaiable.
+ * - E_CONNMAN_EVENT_MANAGER_OUT: issued when connman connection is lost.
+ * - E_CONNMAN_EVENT_ELEMENT_ADD: element was added.
+ * - E_CONNMAN_EVENT_ELEMENT_DEL: element was deleted.
+ * - E_CONNMAN_EVENT_ELEMENT_UPDATED: element was updated (properties
+ * or state changed).
+ *
+ * Manager IN/OUT events do not provide any event information, just
+ * tells you that system is usable or not. After manager is out, all
+ * elements will be removed, so after this event do not use the system anymore.
+ *
+ * Element events will give you an element object. After DEL event callback
+ * returns, that element will not be valid anymore.
+ */
+unsigned int
+e_connman_system_init(E_DBus_Connection *edbus_conn)
+{
+ init_count++;
+
+ if (init_count > 1)
+ return init_count;
+
+ if (!eina_init())
+ fputs("ERROR: Error during the initialization of eina.\n", stderr);
+
+ if (E_CONNMAN_EVENT_MANAGER_IN == 0)
+ E_CONNMAN_EVENT_MANAGER_IN = ecore_event_type_new();
+ if (E_CONNMAN_EVENT_MANAGER_OUT == 0)
+ E_CONNMAN_EVENT_MANAGER_OUT = ecore_event_type_new();
+ if (E_CONNMAN_EVENT_ELEMENT_ADD == 0)
+ E_CONNMAN_EVENT_ELEMENT_ADD = ecore_event_type_new();
+ if (E_CONNMAN_EVENT_ELEMENT_DEL == 0)
+ E_CONNMAN_EVENT_ELEMENT_DEL = ecore_event_type_new();
+ if (E_CONNMAN_EVENT_ELEMENT_UPDATED == 0)
+ E_CONNMAN_EVENT_ELEMENT_UPDATED = ecore_event_type_new();
+
+ if (e_connman_iface_manager == NULL)
+ e_connman_iface_manager = eina_stringshare_add("org.moblin.connman.Manager");
+ if (e_connman_iface_network == NULL)
+ e_connman_iface_network = eina_stringshare_add("org.moblin.connman.Network");
+ if (e_connman_iface_profile == NULL)
+ e_connman_iface_profile = eina_stringshare_add("org.moblin.connman.Profile");
+ if (e_connman_iface_service == NULL)
+ e_connman_iface_service = eina_stringshare_add("org.moblin.connman.Service");
+ if (e_connman_iface_device == NULL)
+ e_connman_iface_device = eina_stringshare_add("org.moblin.connman.Device");
+ if (e_connman_iface_connection == NULL)
+ e_connman_iface_connection = eina_stringshare_add("org.moblin.connman.Connection");
+
+ if (e_connman_prop_available == NULL)
+ e_connman_prop_available = eina_stringshare_add("Available");
+ if (e_connman_prop_connected == NULL)
+ e_connman_prop_connected = eina_stringshare_add("Connected");
+ if (e_connman_prop_connections == NULL)
+ e_connman_prop_connections = eina_stringshare_add("Connections");
+ if (e_connman_prop_default == NULL)
+ e_connman_prop_default = eina_stringshare_add("Default");
+ if (e_connman_prop_device == NULL)
+ e_connman_prop_device = eina_stringshare_add("Device");
+ if (e_connman_prop_devices == NULL)
+ e_connman_prop_devices = eina_stringshare_add("Devices");
+ if (e_connman_prop_interface == NULL)
+ e_connman_prop_interface = eina_stringshare_add("Interface");
+ if (e_connman_prop_ipv4_address == NULL)
+ e_connman_prop_ipv4_address = eina_stringshare_add("IPv4.Address");
+ if (e_connman_prop_ipv4_method == NULL)
+ e_connman_prop_ipv4_method = eina_stringshare_add("IPv4.Method");
+ if (e_connman_prop_name == NULL)
+ e_connman_prop_name = eina_stringshare_add("Name");
+ if (e_connman_prop_network == NULL)
+ e_connman_prop_network = eina_stringshare_add("Network");
+ if (e_connman_prop_networks == NULL)
+ e_connman_prop_networks = eina_stringshare_add("Networks");
+ if (e_connman_prop_offline_mode == NULL)
+ e_connman_prop_offline_mode = eina_stringshare_add("OfflineMode");
+ if (e_connman_prop_policy == NULL)
+ e_connman_prop_policy = eina_stringshare_add("Policy");
+ if (e_connman_prop_powered == NULL)
+ e_connman_prop_powered = eina_stringshare_add("Powered");
+ if (e_connman_prop_priority == NULL)
+ e_connman_prop_priority = eina_stringshare_add("Priority");
+ if (e_connman_prop_profiles == NULL)
+ e_connman_prop_profiles = eina_stringshare_add("Profiles");
+ if (e_connman_prop_remember == NULL)
+ e_connman_prop_remember = eina_stringshare_add("Remember");
+ if (e_connman_prop_scan_interval == NULL)
+ e_connman_prop_scan_interval = eina_stringshare_add("ScanInterval");
+ if (e_connman_prop_scanning == NULL)
+ e_connman_prop_scanning = eina_stringshare_add("Scanning");
+ if (e_connman_prop_state == NULL)
+ e_connman_prop_state = eina_stringshare_add("State");
+ if (e_connman_prop_strengh == NULL)
+ e_connman_prop_strengh = eina_stringshare_add("Strength");
+ if (e_connman_prop_type == NULL)
+ e_connman_prop_type = eina_stringshare_add("Type");
+ if (e_connman_prop_wifi_mode == NULL)
+ e_connman_prop_wifi_mode = eina_stringshare_add("WiFi.Mode");
+ if (e_connman_prop_wifi_passphrase == NULL)
+ e_connman_prop_wifi_passphrase = eina_stringshare_add("WiFi.Passphrase");
+ if (e_connman_prop_wifi_security == NULL)
+ e_connman_prop_wifi_security = eina_stringshare_add("WiFi.Security");
+ if (e_connman_prop_wifi_ssid == NULL)
+ e_connman_prop_wifi_ssid = eina_stringshare_add("WiFi.SSID");
+
+ e_connman_conn = edbus_conn;
+ cb_name_owner_changed = e_dbus_signal_handler_add
+ (e_connman_conn, fdo_bus_name, fdo_path, fdo_interface, "NameOwnerChanged",
+ _e_connman_system_name_owner_changed, NULL);
+
+ if (pending_get_name_owner)
+ dbus_pending_call_cancel(pending_get_name_owner);
+
+ pending_get_name_owner = e_dbus_get_name_owner
+ (e_connman_conn, bus_name, _e_connman_get_name_owner, NULL);
+
+ e_connman_elements_init();
+
+ return init_count;
+}
+
+static inline void
+_stringshare_del(const char **str)
+{
+ if (!*str)
+ return;
+ eina_stringshare_del(*str);
+ *str = NULL;
+}
+
+/**
+ * Shutdown connman system.
+ *
+ * When count drops to 0 resources will be released and no calls should be
+ * made anymore.
+ */
+unsigned int
+e_connman_system_shutdown(void)
+{
+ if (init_count == 0)
+ {
+ fputs("ERROR: connman system already shutdown.\n", stderr);
+ return 0;
+ }
+ init_count--;
+ if (init_count > 0)
+ return init_count;
+
+ _stringshare_del(&e_connman_iface_manager);
+ _stringshare_del(&e_connman_iface_network);
+ _stringshare_del(&e_connman_iface_profile);
+ _stringshare_del(&e_connman_iface_service);
+ _stringshare_del(&e_connman_iface_device);
+ _stringshare_del(&e_connman_iface_connection);
+
+ _stringshare_del(&e_connman_prop_available);
+ _stringshare_del(&e_connman_prop_connected);
+ _stringshare_del(&e_connman_prop_connections);
+ _stringshare_del(&e_connman_prop_default);
+ _stringshare_del(&e_connman_prop_device);
+ _stringshare_del(&e_connman_prop_devices);
+ _stringshare_del(&e_connman_prop_interface);
+ _stringshare_del(&e_connman_prop_ipv4_address);
+ _stringshare_del(&e_connman_prop_ipv4_method);
+ _stringshare_del(&e_connman_prop_name);
+ _stringshare_del(&e_connman_prop_network);
+ _stringshare_del(&e_connman_prop_networks);
+ _stringshare_del(&e_connman_prop_offline_mode);
+ _stringshare_del(&e_connman_prop_policy);
+ _stringshare_del(&e_connman_prop_powered);
+ _stringshare_del(&e_connman_prop_priority);
+ _stringshare_del(&e_connman_prop_profiles);
+ _stringshare_del(&e_connman_prop_remember);
+ _stringshare_del(&e_connman_prop_scan_interval);
+ _stringshare_del(&e_connman_prop_scanning);
+ _stringshare_del(&e_connman_prop_state);
+ _stringshare_del(&e_connman_prop_strengh);
+ _stringshare_del(&e_connman_prop_type);
+ _stringshare_del(&e_connman_prop_wifi_mode);
+ _stringshare_del(&e_connman_prop_wifi_passphrase);
+ _stringshare_del(&e_connman_prop_wifi_security);
+ _stringshare_del(&e_connman_prop_wifi_ssid);
+
+ if (pending_get_name_owner)
+ {
+ dbus_pending_call_cancel(pending_get_name_owner);
+ pending_get_name_owner = NULL;
+ }
+
+ if (cb_name_owner_changed)
+ {
+ e_dbus_signal_handler_del(e_connman_conn, cb_name_owner_changed);
+ cb_name_owner_changed = NULL;
+ }
+
+ if (unique_name)
+ _e_connman_system_name_owner_exit();
+
+ e_connman_elements_shutdown();
+ eina_shutdown();
+ e_connman_conn = NULL;
+
+ return init_count;
+}
--- /dev/null
+#include "e_connman_private.h"
+
+E_Connman_Element *
+e_connman_connection_get(const char *path)
+{
+ E_Connman_Element *connection;
+
+ EINA_SAFETY_ON_NULL_RETURN_VAL(path, NULL);
+
+ connection = e_connman_element_get(path);
+ if (!connection)
+ return NULL;
+
+ if (!e_connman_element_is_connection(connection))
+ {
+ WRN("path '%s' is not a connection!\n", path);
+ return NULL;
+ }
+
+ return connection;
+}
+
+/**
+ * Get property "Type" value.
+ *
+ * If this property isn't found then 0 is returned.
+ * If zero is returned, then this call failed and parameter-returned
+ * values shall be considered invalid.
+ *
+ * The connection type (for example "wifi", etc.)
+ *
+ * @param connection_path to get property.
+ * @param type where to store the property value, must be a pointer
+ * to string (const char **), it will not be allocated or
+ * copied and references will be valid until element changes,
+ * so copy it if you want to use it later.
+ *
+ * @return 1 on success, 0 otherwise.
+ */
+bool
+e_connman_connection_type_get(const E_Connman_Element *connection, const char **type)
+{
+ EINA_SAFETY_ON_NULL_RETURN_VAL(connection, 0);
+ EINA_SAFETY_ON_NULL_RETURN_VAL(type, 0);
+ return e_connman_element_property_get_stringshared
+ (connection, e_connman_prop_type, NULL, type);
+}
+
+/**
+ * Get property "Interface" value.
+ *
+ * If this property isn't found then 0 is returned.
+ * If zero is returned, then this call failed and parameter-returned
+ * values shall be considered invalid.
+ *
+ * The connection interface (for example "eth0" etc.)
+ *
+ * This value is for pure informational purposes. It
+ * is not guaranteed that it is always present.
+ *
+ * @param connection_path to get property.
+ * @param interface where to store the property value, must be a pointer
+ * to string (const char **), it will not be allocated or
+ * copied and references will be valid until element changes,
+ * so copy it if you want to use it later.
+ *
+ * @return 1 on success, 0 otherwise.
+ */
+bool
+e_connman_connection_interface_get(const E_Connman_Element *connection, const char **interface)
+{
+ EINA_SAFETY_ON_NULL_RETURN_VAL(connection, 0);
+ EINA_SAFETY_ON_NULL_RETURN_VAL(interface, 0);
+ return e_connman_element_property_get_stringshared
+ (connection, e_connman_prop_interface, NULL, interface);
+}
+
+/**
+ * Get property "Strength" value.
+ *
+ * If this property isn't found then 0 is returned.
+ * If zero is returned, then this call failed and parameter-returned
+ * values shall be considered invalid.
+ *
+ * Indicates the signal strength of the connection.
+ *
+ * This property is optional and not always present.
+ *
+ * @param connection_path to get property.
+ * @param strength where to store the property value, must be a pointer
+ * to byte (unsigned char*).
+ *
+ * @return 1 on success, 0 otherwise.
+ */
+bool
+e_connman_connection_strength_get(const E_Connman_Element *connection, unsigned char *strength)
+{
+ EINA_SAFETY_ON_NULL_RETURN_VAL(connection, 0);
+ EINA_SAFETY_ON_NULL_RETURN_VAL(strength, 0);
+ return e_connman_element_property_get_stringshared
+ (connection, e_connman_prop_strengh, NULL, strength);
+}
+
+/**
+ * Get property "Default" value.
+ *
+ * If this property isn't found then 0 is returned.
+ * If zero is returned, then this call failed and parameter-returned
+ * values shall be considered invalid.
+ *
+ * Indicates if it is a default connection. It is
+ * possible to have multiple default connections.
+ *
+ * @param connection_path to get property.
+ * @param connection_default where to store the property value, must be a
+ * pointer to boolean (bool *).
+ *
+ * @return 1 on success, 0 otherwise.
+ */
+bool
+e_connman_connection_default_get(const E_Connman_Element *connection, bool *connection_default)
+{
+ EINA_SAFETY_ON_NULL_RETURN_VAL(connection, 0);
+ EINA_SAFETY_ON_NULL_RETURN_VAL(connection_default, 0);
+ return e_connman_element_property_get_stringshared
+ (connection, e_connman_prop_default, NULL, connection_default);
+}
+
+/**
+ * Get the device element this connection has
+ * been established with.
+ *
+ * @param connection_path to get property.
+ * @param element where to store element, just changed if return is 1
+ *
+ * @return 1 on success, 0 otherwise.
+ */
+bool
+e_connman_connection_device_get(const E_Connman_Element *connection, E_Connman_Element **element)
+{
+ const char *device_path;
+ EINA_SAFETY_ON_NULL_RETURN_VAL(connection, 0);
+ EINA_SAFETY_ON_NULL_RETURN_VAL(element, 0);
+ if (!e_connman_element_property_get_stringshared
+ (connection, e_connman_prop_device, NULL, &device_path))
+ return 0;
+ *element = e_connman_element_get(device_path);
+ return 1;
+}
+
+/**
+ * Get the network element this connection
+ * belongs to.
+ *
+ * @param connection_path to get property.
+ * @param element where to store element, just changed if return is 1
+ *
+ * @return 1 on success, 0 otherwise.
+ */
+bool
+e_connman_connection_network_get(const E_Connman_Element *connection, E_Connman_Element **element)
+{
+ const char *network_path;
+ EINA_SAFETY_ON_NULL_RETURN_VAL(connection, 0);
+ EINA_SAFETY_ON_NULL_RETURN_VAL(element, 0);
+ if (!e_connman_element_property_get_stringshared
+ (connection, e_connman_prop_network, NULL, &network_path))
+ return 0;
+ *element = e_connman_element_get(network_path);
+ return 1;
+}
+
+/**
+ * Get property "IPv4.Method" value.
+ *
+ * If this property isn't found then 0 is returned.
+ * If zero is returned, then this call failed and parameter-returned
+ * values shall be considered invalid.
+ *
+ * Indicates the way how the IPv4 settings were
+ * configured. Possible values here are "dhcp"
+ * and "static".
+ *
+ * @param connection_path to get property.
+ * @param method where to store the property value, must be a pointer
+ * to string (const char **), it will not be allocated or
+ * copied and references will be valid until element changes,
+ * so copy it if you want to use it later.
+ *
+ * @return 1 on success, 0 otherwise.
+ */
+bool
+e_connman_connection_ipv4_method_get(const E_Connman_Element *connection, const char **method)
+{
+ EINA_SAFETY_ON_NULL_RETURN_VAL(connection, 0);
+ EINA_SAFETY_ON_NULL_RETURN_VAL(method, 0);
+ return e_connman_element_property_get_stringshared
+ (connection, e_connman_prop_ipv4_method, NULL, method);
+}
+
+/**
+ * Get property "IPv4.Address" value.
+ *
+ * If this property isn't found then 0 is returned.
+ * If zero is returned, then this call failed and parameter-returned
+ * values shall be considered invalid.
+ *
+ * Shows the current configured IPv4 address.
+ *
+ * @param connection_path to get property.
+ * @param address where to store the property value, must be a pointer
+ * to string (const char **), it will not be allocated or
+ * copied and references will be valid until element changes,
+ * so copy it if you want to use it later.
+ *
+ * @return 1 on success, 0 otherwise.
+ */
+bool
+e_connman_connection_ipv4_address_get(const E_Connman_Element *connection, const char **address)
+{
+ EINA_SAFETY_ON_NULL_RETURN_VAL(connection, 0);
+ EINA_SAFETY_ON_NULL_RETURN_VAL(address, 0);
+ return e_connman_element_property_get_stringshared
+ (connection, e_connman_prop_ipv4_address, NULL, address);
+}
--- /dev/null
+#include "e_connman_private.h"
+
+E_Connman_Element *
+e_connman_device_get(const char *path)
+{
+ E_Connman_Element *device;
+
+ EINA_SAFETY_ON_NULL_RETURN_VAL(path, NULL);
+
+ device = e_connman_element_get(path);
+ if (!device)
+ return NULL;
+
+ if (!e_connman_element_is_device(device))
+ {
+ WRN("path '%s' is not a device!\n", path);
+ return NULL;
+ }
+
+ return device;
+}
+
+static void
+_e_connman_device_network_create_callback(void *user_data, DBusMessage *msg, DBusError *err)
+{
+ WRN("FIXME need to receive the network object path\n");
+}
+
+/**
+ * Creates a network object from the specified properties. Valid
+ * properties are WiFi.SSID, WiFi.Security and WiFi.Passphrase.
+ *
+ * Call method CreateNetwork(dict_network) at the given device
+ * on server.
+ *
+ * @param device_path to call method on server.
+ * @param cb function to call when server replies or some error happens.
+ * @param data data to give to cb when it is called.
+ *
+ * @return 1 on success, 0 otherwise.
+ */
+bool
+e_connman_device_network_create(E_Connman_Element *device, E_DBus_Method_Return_Cb cb, const void *data)
+{
+ const char name[] = "CreateNetwork";
+ DBusMessageIter itr, v;
+ DBusMessage *msg;
+
+ EINA_SAFETY_ON_NULL_RETURN_VAL(device, 0);
+
+ msg = dbus_message_new_method_call
+ (e_connman_system_bus_name_get(), device->path, device->interface,
+ name);
+
+ if (!msg)
+ return 0;
+
+ dbus_message_iter_init_append(msg, &itr);
+ dbus_message_iter_open_container(&itr, 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, &v);
+
+ /* FIXME need to create the message */
+
+ dbus_message_iter_close_container(&itr, &v);
+ return e_connman_element_message_send
+ (device, name, _e_connman_device_network_create_callback,
+ msg, &device->_pending.network_create, cb, data);
+}
+
+/**
+ * Removes a previoulsy created network object.
+ *
+ * Call method RemoveNetwork(network) at the given device on server in order to remove
+ * it.
+ *
+ * @param device_path to call method on server.
+ * @param network_path network path to be removed.
+ * @param cb function to call when server replies or some error happens.
+ * @param data data to give to cb when it is called.
+ *
+ * @return 1 on success, 0 otherwise.
+ */
+bool
+e_connman_device_network_remove(E_Connman_Element *device, const char *network_path, E_DBus_Method_Return_Cb cb, const void *data)
+{
+ const char name[] = "RemoveNetwork";
+
+ EINA_SAFETY_ON_NULL_RETURN_VAL(device, 0);
+ EINA_SAFETY_ON_NULL_RETURN_VAL(network_path, 0);
+ return e_connman_element_call_with_path
+ (device, name, network_path, NULL,
+ &device->_pending.network_remove, cb, data);
+}
+
+/**
+ * Propose device to scan.
+ *
+ * Call method ProposeScan() at the given device on server in order to propose it
+ * to scan.
+ *
+ * @param device_path to call method on server.
+ * @param cb function to call when server replies or some error happens.
+ * @param data data to give to cb when it is called.
+ *
+ * @return 1 on success, 0 otherwise.
+ */
+bool
+e_connman_device_propose_scan(E_Connman_Element *device, E_DBus_Method_Return_Cb cb, const void *data)
+{
+ const char name[] = "ProposeScan";
+
+ EINA_SAFETY_ON_NULL_RETURN_VAL(device, 0);
+ return e_connman_element_call_full
+ (device, name, NULL, &device->_pending.device_propose_scan, cb, data);
+}
+
+/**
+ * Get property "Name" value.
+ *
+ * If this property isn't found then 0 is returned.
+ * If zero is returned, then this call failed and parameter-returned
+ * values shall be considered invalid.
+ *
+ * The device name (for example "Wireless" etc.)
+ *
+ * This name can be used for directly displaying it in
+ * the application. It has pure informational purpose.
+ *
+ * @param device_path to get property.
+ * @param name where to store the property value, must be a pointer
+ * to string (const char **), it will not be allocated or
+ * copied and references will be valid until element changes,
+ * so copy it if you want to use it later.
+ *
+ * @return 1 on success, 0 otherwise.
+ */
+bool
+e_connman_device_name_get(const E_Connman_Element *device, const char **name)
+{
+ EINA_SAFETY_ON_NULL_RETURN_VAL(device, 0);
+ EINA_SAFETY_ON_NULL_RETURN_VAL(name, 0);
+ return e_connman_element_property_get_stringshared
+ (device, e_connman_prop_name, NULL, name);
+}
+
+/**
+ * Get property "Type" value.
+ *
+ * If this property isn't found then 0 is returned.
+ * If zero is returned, then this call failed and parameter-returned
+ * values shall be considered invalid.
+ *
+ * The device type (for example "ethernet", "wifi" etc.)
+ *
+ * @param device_path to get property.
+ * @param type where to store the property value, must be a pointer
+ * to string (const char **), it will not be allocated or
+ * copied and references will be valid until element changes,
+ * so copy it if you want to use it later.
+ *
+ * @return 1 on success, 0 otherwise.
+ */
+bool
+e_connman_device_type_get(const E_Connman_Element *device, const char **type)
+{
+ EINA_SAFETY_ON_NULL_RETURN_VAL(device, 0);
+ EINA_SAFETY_ON_NULL_RETURN_VAL(type, 0);
+ return e_connman_element_property_get_stringshared
+ (device, e_connman_prop_type, NULL, type);
+}
+
+/**
+ * Get property "Interface" value.
+ *
+ * If this property isn't found then 0 is returned.
+ * If zero is returned, then this call failed and parameter-returned
+ * values shall be considered invalid.
+ *
+ * The device interface (for example "eth0" etc.)
+ *
+ * This value is for pure informational purposes. It
+ * is not guaranteed that it is always present.
+ *
+ * @param device_path to get property.
+ * @param interface where to store the property value, must be a pointer
+ * to string (const char **), it will not be allocated or
+ * copied and references will be valid until element changes,
+ * so copy it if you want to use it later.
+ *
+ * @return 1 on success, 0 otherwise.
+ */
+bool
+e_connman_device_interface_get(const E_Connman_Element *device, const char **interface)
+{
+ EINA_SAFETY_ON_NULL_RETURN_VAL(device, 0);
+ EINA_SAFETY_ON_NULL_RETURN_VAL(interface, 0);
+ return e_connman_element_property_get_stringshared
+ (device, e_connman_prop_interface, NULL, interface);
+}
+
+/**
+ * Get property "Policy" value.
+ *
+ * If this property isn't found then 0 is returned.
+ * If zero is returned, then this call failed and parameter-returned
+ * values shall be considered invalid.
+ *
+ * Setting of the device power and connection policy.
+ * Possible values are "ignore", "off", "auto"
+ * and "manual".
+ *
+ * The policy defines on how the device is initialized
+ * when brought up and how it connects. The actual
+ * device power state can be changed independently to
+ * this value.
+ *
+ * If a device is switched off and the policy is changed
+ * to "auto" or "manual", the device will be switched
+ * on. For a current active device changing the policy
+ * to "off" results in powering down the device.
+ *
+ * The "ignore" policy can be set for devices that are
+ * detected, but managed by a different entity on the
+ * system. For example for complex network setups.
+ *
+ * Devices that can connect to various networks, the
+ * difference between "auto" or "manual" defines if
+ * known networks are connected automatically or not.
+ * For simple devices like Ethernet cards, setting
+ * the "manual" policy might fail.
+ *
+ * @param device_path to get property.
+ * @param policy where to store the property value, must be a pointer
+ * to string (const char **), it will not be allocated or
+ * copied and references will be valid until element changes,
+ * so copy it if you want to use it later.
+ *
+ * @return 1 on success, 0 otherwise.
+ * @see e_connman_device_policy_set()
+ */
+bool
+e_connman_device_policy_get(const E_Connman_Element *device, const char **policy)
+{
+ EINA_SAFETY_ON_NULL_RETURN_VAL(device, 0);
+ EINA_SAFETY_ON_NULL_RETURN_VAL(policy, 0);
+ return e_connman_element_property_get_stringshared
+ (device, e_connman_prop_policy, NULL, policy);
+}
+
+/**
+ * Call method SetProperty("Policy", policy) at the given element on server.
+ *
+ * This is a server call, not local, so it may fail and in that case
+ * no property is updated locally. If the value was set the event
+ * E_CONNMAN_EVENT_ELEMENT_UPDATED will be added to main loop.
+ *
+ * Setting of the device power and connection policy.
+ * Possible values are "ignore", "off", "auto"
+ * and "manual".
+ *
+ * The policy defines on how the device is initialized
+ * when brought up and how it connects. The actual
+ * device power state can be changed independently to
+ * this value.
+ *
+ * If a device is switched off and the policy is changed
+ * to "auto" or "manual", the device will be switched
+ * on. For a current active device changing the policy
+ * to "off" results in powering down the device.
+ *
+ * The "ignore" policy can be set for devices that are
+ * detected, but managed by a different entity on the
+ * system. For example for complex network setups.
+ *
+ * Devices that can connect to various networks, the
+ * difference between "auto" or "manual" defines if
+ * known networks are connected automatically or not.
+ * For simple devices like Ethernet cards, setting
+ * the "manual" policy might fail.
+ *
+ * @param device_path to set property.
+ * @param policy value to set.
+ * @param cb function to call when server replies or some error happens.
+ * @param data data to give to cb when it is called.
+ *
+ * @return 1 on success, 0 otherwise.
+ * @see e_connman_device_policy_get()
+ */
+bool
+e_connman_device_policy_set(E_Connman_Element *device, const char *policy, E_DBus_Method_Return_Cb cb, const void *data)
+{
+ EINA_SAFETY_ON_NULL_RETURN_VAL(device, 0);
+ EINA_SAFETY_ON_NULL_RETURN_VAL(policy, 0);
+ return e_connman_element_property_set_full
+ (device, e_connman_prop_policy, DBUS_TYPE_STRING, policy, cb, data);
+}
+
+/**
+ * Get property "Priority" value.
+ *
+ * If this property isn't found then 0 is returned.
+ * If zero is returned, then this call failed and parameter-returned
+ * values shall be considered invalid.
+ *
+ * The device priority. Higher values indicate the
+ * preference for this device.
+ *
+ * @param device_path to get property.
+ * @param priority where to store the property value, must be a pointer
+ * to byte (unsigned char *).
+ *
+ * @return 1 on success, 0 otherwise.
+ * @see e_connman_device_priority_set()
+ */
+bool
+e_connman_device_priority_get(const E_Connman_Element *device, unsigned char *priority)
+{
+ EINA_SAFETY_ON_NULL_RETURN_VAL(device, 0);
+ EINA_SAFETY_ON_NULL_RETURN_VAL(priority, 0);
+ return e_connman_element_property_get_stringshared
+ (device, e_connman_prop_priority, NULL, priority);
+}
+
+/**
+ * Call method SetProperty("Priority", priority) at the given element on server.
+ *
+ * This is a server call, not local, so it may fail and in that case
+ * no property is updated locally. If the value was set the event
+ * E_CONNMAN_EVENT_ELEMENT_UPDATED will be added to main loop.
+ *
+ * The device priority. Higher values indicate the
+ * preference for this device.
+ *
+ * @param device_path to set property.
+ * @param priority value to set.
+ * @param cb function to call when server replies or some error happens.
+ * @param data data to give to cb when it is called.
+ *
+ * @return 1 on success, 0 otherwise.
+ * @see e_connman_device_priority_get()
+ */
+bool
+e_connman_device_priority_set(E_Connman_Element *device, unsigned char priority, E_DBus_Method_Return_Cb cb, const void *data)
+{
+ EINA_SAFETY_ON_NULL_RETURN_VAL(device, 0);
+ return e_connman_element_property_set_full
+ (device, e_connman_prop_priority, DBUS_TYPE_BYTE, &priority, cb, data);
+}
+
+/**
+ * Get property "Powered" value.
+ *
+ * If this property isn't found then 0 is returned.
+ * If zero is returned, then this call failed and parameter-returned
+ * values shall be considered invalid.
+ *
+ * Switch a device on or off. This will also modify
+ * the list of networks in range. All known networks
+ * will be still available via the Networks property.
+ *
+ * Changing this value doesn't change the value of the
+ * Policy property.
+ *
+ * The value of this property can be changed by other
+ * parts of the system (including the kernel). An
+ * example would be modifications via the "ifconfig"
+ * command line utility.
+ *
+ * @param device_path to get property.
+ * @param powered where to store the property value, must be a pointer
+ * to boolean (bool *).
+ *
+ * @return 1 on success, 0 otherwise.
+ * @see e_connman_device_powered_set()
+ */
+bool
+e_connman_device_powered_get(const E_Connman_Element *device, bool *powered)
+{
+ EINA_SAFETY_ON_NULL_RETURN_VAL(device, 0);
+ EINA_SAFETY_ON_NULL_RETURN_VAL(powered, 0);
+ return e_connman_element_property_get_stringshared
+ (device, e_connman_prop_powered, NULL, powered);
+}
+
+/**
+ * Call method SetProperty("Powered", powered) at the given element on server.
+ *
+ * This is a server call, not local, so it may fail and in that case
+ * no property is updated locally. If the value was set the event
+ * E_CONNMAN_EVENT_ELEMENT_UPDATED will be added to main loop.
+ *
+ * Switch a device on or off. This will also modify
+ * the list of networks in range. All known networks
+ * will be still available via the Networks property.
+ *
+ * Changing this value doesn't change the value of the
+ * Policy property.
+ *
+ * The value of this property can be changed by other
+ * parts of the system (including the kernel). An
+ * example would be modifications via the "ifconfig"
+ * command line utility.
+ *
+ * @param device_path to set property.
+ * @param powered value to set.
+ * @param cb function to call when server replies or some error happens.
+ * @param data data to give to cb when it is called.
+ *
+ * @return 1 on success, 0 otherwise.
+ * @see e_connman_device_powered_get()
+ */
+bool
+e_connman_device_powered_set(E_Connman_Element *device, bool powered, E_DBus_Method_Return_Cb cb, const void *data)
+{
+ EINA_SAFETY_ON_NULL_RETURN_VAL(device, 0);
+ return e_connman_element_property_set_full
+ (device, e_connman_prop_powered, DBUS_TYPE_BOOLEAN, &powered, cb, data);
+}
+
+/**
+ * Get property "ScanInterval" value.
+ *
+ * If this property isn't found then 0 is returned.
+ * If zero is returned, then this call failed and parameter-returned
+ * values shall be considered invalid.
+ *
+ * The scan interval describes the time in seconds
+ * between automated scan attempts. Setting this
+ * value to 0 will disable the background scanning.
+ *
+ * The default value is 300 and so every 5 minutes
+ * a scan procedure will be triggered.
+ *
+ * This property is not available with all types
+ * of devices. Some might not support background
+ * scanning at all.
+ *
+ * @param device_path to get property.
+ * @param scan_interval where to store the property value, must be a pointer
+ * to uint16 (unsigned short *).
+ *
+ * @return 1 on success, 0 otherwise.
+ * @see e_connman_device_scan_interval_set()
+ */
+bool
+e_connman_device_scan_interval_get(const E_Connman_Element *device, unsigned short *scan_interval)
+{
+ EINA_SAFETY_ON_NULL_RETURN_VAL(device, 0);
+ EINA_SAFETY_ON_NULL_RETURN_VAL(scan_interval, 0);
+ return e_connman_element_property_get_stringshared
+ (device, e_connman_prop_scan_interval, NULL, scan_interval);
+}
+
+/**
+ * Call method SetProperty("ScanInterval", scan_interval) at the given element on server.
+ *
+ * This is a server call, not local, so it may fail and in that case
+ * no property is updated locally. If the value was set the event
+ * E_CONNMAN_EVENT_ELEMENT_UPDATED will be added to main loop.
+ *
+ * The scan interval describes the time in seconds
+ * between automated scan attempts. Setting this
+ * value to 0 will disable the background scanning.
+ *
+ * The default value is 300 and so every 5 minutes
+ * a scan procedure will be triggered.
+ *
+ * This property is not available with all types
+ * of devices. Some might not support background
+ * scanning at all.
+ *
+ * @param device_path to set property.
+ * @param scan_interval value to set.
+ * @param cb function to call when server replies or some error happens.
+ * @param data data to give to cb when it is called.
+ *
+ * @return 1 on success, 0 otherwise.
+ * @see e_connman_device_scan_interval_get()
+ */
+bool
+e_connman_device_scan_interval_set(E_Connman_Element *device, unsigned short scan_interval, E_DBus_Method_Return_Cb cb, const void *data)
+{
+ EINA_SAFETY_ON_NULL_RETURN_VAL(device, 0);
+ return e_connman_element_property_set_full
+ (device, e_connman_prop_scan_interval, DBUS_TYPE_UINT16,
+ &scan_interval, cb, data);
+}
+
+/**
+ * Get property "Scanning" value.
+ *
+ * If this property isn't found then 0 is returned.
+ * If zero is returned, then this call failed and parameter-returned
+ * values shall be considered invalid.
+ *
+ * Indicates if a device is scanning. Not all device
+ * types might support this. Also some hardware might
+ * execute background scanning without notifying the
+ * driver about it. Use this property only for visual
+ * indication.
+ *
+ * @param device_path to get property.
+ * @param scanning where to store the property value, must be a pointer
+ * to boolean (bool *).
+ *
+ * @return 1 on success, 0 otherwise.
+ */
+bool
+e_connman_device_scanning_get(const E_Connman_Element *device, bool *scanning)
+{
+ EINA_SAFETY_ON_NULL_RETURN_VAL(device, 0);
+ EINA_SAFETY_ON_NULL_RETURN_VAL(scanning, 0);
+ return e_connman_element_property_get_stringshared
+ (device, e_connman_prop_scanning, NULL, scanning);
+}
+
+/**
+ * Get array of network elements.
+ *
+ * @param device_path to get property.
+ * @param count return the number of elements in array.
+ * @param elements where to store elements array, just changed if return is 1.
+ * Elements are not referenced and in no particular order.
+ *
+ * @return 1 on success, 0 otherwise.
+ */
+bool
+e_connman_device_networks_get(const E_Connman_Element *device, unsigned int *count, E_Connman_Element ***elements)
+{
+ EINA_SAFETY_ON_NULL_RETURN_VAL(device, 0);
+ EINA_SAFETY_ON_NULL_RETURN_VAL(count, 0);
+ EINA_SAFETY_ON_NULL_RETURN_VAL(elements, 0);
+ return e_connman_element_objects_array_get_stringshared
+ (device, e_connman_prop_networks, count, elements);
+}
--- /dev/null
+#include "e_connman_private.h"
+#include <string.h>
+#include <errno.h>
+
+static Eina_Hash *elements = NULL;
+
+typedef struct _E_Connman_Array E_Connman_Array;
+typedef struct _E_Connman_Element_Pending E_Connman_Element_Pending;
+typedef struct _E_Connman_Element_Call_Data E_Connman_Element_Call_Data;
+typedef struct _E_Connman_Element_Property E_Connman_Element_Property;
+typedef struct _E_Connman_Element_Listener E_Connman_Element_Listener;
+
+struct _E_Connman_Array
+{
+ int type;
+ Eina_Array *array;
+};
+
+struct _E_Connman_Element_Pending
+{
+ EINA_INLIST;
+ DBusPendingCall *pending;
+ void *data;
+ E_DBus_Method_Return_Cb user_cb;
+ void *user_data;
+};
+
+struct _E_Connman_Element_Call_Data
+{
+ E_Connman_Element *element;
+ E_DBus_Method_Return_Cb cb;
+ E_Connman_Element_Pending *pending;
+ Eina_Inlist **p_list;
+};
+
+struct _E_Connman_Element_Property
+{
+ EINA_INLIST;
+ const char *name;
+ int type;
+ union {
+ bool boolean;
+ const char *str;
+ unsigned short u16;
+ unsigned int u32;
+ unsigned char byte;
+ const char *path;
+ void *variant;
+ E_Connman_Array *array;
+ } value;
+};
+
+struct _E_Connman_Element_Listener
+{
+ EINA_INLIST;
+ void (*cb)(void *data, const E_Connman_Element *element);
+ void *data;
+ void (*free_data)(void *data);
+};
+
+
+static void
+_e_connman_element_event_no_free(void *data, void *ev)
+{
+ E_Connman_Element *element = ev;
+ e_connman_element_unref(element);
+}
+
+static void
+e_connman_element_event_add(int event_type, E_Connman_Element *element)
+{
+ e_connman_element_ref(element);
+ ecore_event_add
+ (event_type, element, _e_connman_element_event_no_free, element);
+}
+
+static void
+e_connman_element_call_dispatch_and_free(void *d, DBusMessage *msg, DBusError *err)
+{
+ E_Connman_Element_Call_Data *data = d;
+ E_Connman_Element_Pending *pending;
+
+ pending = data->pending;
+ pending->pending = NULL;
+
+ if (data->cb)
+ data->cb(data->element, msg, err);
+
+ if (pending->user_cb)
+ pending->user_cb(pending->user_data, msg, err);
+
+ pending->data = NULL;
+ *data->p_list = eina_inlist_remove(*data->p_list, EINA_INLIST_GET(pending));
+ free(pending);
+ free(data);
+}
+
+static void
+e_connman_element_pending_cancel_and_free(Eina_Inlist **pending)
+{
+ while (*pending)
+ {
+ E_Connman_Element_Pending *p = (E_Connman_Element_Pending *)*pending;
+ DBusError err;
+
+ dbus_pending_call_cancel(p->pending);
+
+ dbus_error_init(&err);
+ dbus_set_error(&err, "Canceled", "Pending method call was canceled.");
+ e_connman_element_call_dispatch_and_free(p->data, NULL, &err);
+ dbus_error_free(&err);
+ }
+}
+
+void
+e_connman_element_listener_add(E_Connman_Element *element, void (*cb)(void *data, const E_Connman_Element *element), const void *data, void (*free_data)(void *data))
+{
+ E_Connman_Element_Listener *l;
+
+ if (!element)
+ {
+ ERR("safety check failed: element == NULL\n");
+ goto error;
+ }
+ if (!cb)
+ {
+ ERR("safety check failed: cb == NULL\n");
+ goto error;
+ }
+
+ l = malloc(sizeof(*l));
+ if (!l)
+ {
+ ERR("could not allocate E_Connman_Element_Listener\n");
+ goto error;
+ }
+
+ l->cb = cb;
+ l->data = (void *)data;
+ l->free_data = free_data;
+
+ element->_listeners = eina_inlist_append
+ (element->_listeners, EINA_INLIST_GET(l));
+
+ return;
+
+ error:
+ if (free_data)
+ free_data((void *)data);
+}
+
+void
+e_connman_element_listener_del(E_Connman_Element *element, void (*cb)(void *data, const E_Connman_Element *element), const void *data)
+{
+ E_Connman_Element_Listener *l;
+
+ EINA_SAFETY_ON_NULL_RETURN(element);
+ EINA_SAFETY_ON_NULL_RETURN(cb);
+
+ EINA_INLIST_FOREACH(element->_listeners, l)
+ if ((l->cb == cb) && (l->data == data))
+ {
+ element->_listeners = eina_inlist_remove
+ (element->_listeners, EINA_INLIST_GET(l));
+ if (l->free_data) l->free_data(l->data);
+ free(l);
+ return;
+ }
+}
+
+static void
+_e_connman_element_listeners_call_do(E_Connman_Element *element)
+{
+ E_Connman_Element_Listener *l, **shadow;
+ unsigned int i, count;
+
+ /* NB: iterate on a copy in order to allow listeners to be deleted
+ * from callbacks. number of listeners should be small, so the
+ * following should do fine.
+ */
+ count = eina_inlist_count(element->_listeners);
+ if (count < 1)
+ goto end;
+
+ shadow = alloca(sizeof(*shadow) * count);
+ if (!shadow)
+ goto end;
+
+ i = 0;
+ EINA_INLIST_FOREACH(element->_listeners, l)
+ shadow[i++] = l;
+
+ for (i = 0; i < count; i++)
+ shadow[i]->cb(shadow[i]->data, element);
+
+ end:
+ e_connman_element_event_add(E_CONNMAN_EVENT_ELEMENT_UPDATED, element);
+}
+
+static int
+_e_connman_element_listeners_call_idler(void *data)
+{
+ E_Connman_Element *element = data;
+ _e_connman_element_listeners_call_do(element);
+ element->_idler.changed = NULL;
+ return 0;
+}
+
+static void
+_e_connman_element_listeners_call(E_Connman_Element *element)
+{
+ if (element->_idler.changed)
+ return;
+ element->_idler.changed = ecore_idler_add
+ (_e_connman_element_listeners_call_idler, element);
+}
+
+/***********************************************************************
+ * Property
+ ***********************************************************************/
+
+static void
+_e_connman_element_array_free(E_Connman_Array *array, E_Connman_Array *new)
+{
+ Eina_Array_Iterator iterator;
+ unsigned int i;
+ void *item;
+
+ if (!array)
+ return;
+
+ switch (array->type)
+ {
+ case DBUS_TYPE_OBJECT_PATH:
+ EINA_ARRAY_ITER_NEXT(array->array, i, item, iterator)
+ eina_stringshare_del(item);
+ break;
+ case DBUS_TYPE_STRING:
+ EINA_ARRAY_ITER_NEXT(array->array, i, item, iterator)
+ eina_stringshare_del(item);
+ break;
+ default:
+ break;
+ }
+ eina_array_free(array->array);
+ free(array);
+}
+
+static void
+_e_connman_element_property_value_free(E_Connman_Element_Property *property)
+{
+ switch (property->type)
+ {
+ case 0:
+ return;
+ case DBUS_TYPE_BOOLEAN:
+ case DBUS_TYPE_BYTE:
+ case DBUS_TYPE_UINT16:
+ case DBUS_TYPE_UINT32:
+ break;
+ case DBUS_TYPE_STRING:
+ eina_stringshare_del(property->value.str);
+ break;
+ case DBUS_TYPE_OBJECT_PATH:
+ eina_stringshare_del(property->value.path);
+ break;
+ case DBUS_TYPE_ARRAY:
+ _e_connman_element_array_free(property->value.array, NULL);
+ break;
+ default:
+ ERR("don't know how to free value of property type %c (%d)\n",
+ property->type, property->type);
+ }
+}
+
+static const char *
+_e_connman_element_get_interface(const char *key)
+{
+ const char *interface = NULL, *tail;
+ char head;
+
+ head = key[0];
+ tail = key + 1;
+
+ switch (head)
+ {
+ case 'P':
+ if (strcmp(tail, "rofiles") == 0)
+ interface = e_connman_iface_profile;
+ break;
+ case 'D':
+ if (strcmp(tail, "evices") == 0)
+ interface = e_connman_iface_device;
+ break;
+ case 'N':
+ if (strcmp(tail, "etworks") == 0)
+ interface = e_connman_iface_network;
+ break;
+ case 'C':
+ if (strcmp(tail, "onnections") == 0)
+ interface = e_connman_iface_connection;
+ break;
+ default:
+ break;
+ }
+
+ if (!interface)
+ ERR("connman reported unknown interface: %s\n", key);
+
+ return interface;
+}
+
+static void
+_e_connman_element_item_register(const char *key, const char *item)
+{
+ E_Connman_Element *element;
+ const char *interface;
+
+ interface = _e_connman_element_get_interface(key);
+ if (!interface)
+ return;
+ element = e_connman_element_register(item, interface);
+ if ((element) && (!e_connman_element_properties_sync(element)))
+ WRN("could not get properties of %s\n", element->path);
+}
+
+static void
+_e_connman_element_objects_array_register(E_Connman_Array *array, const char *name)
+{
+ Eina_Array_Iterator iterator;
+ unsigned int i;
+ void *item;
+
+ if (array->type != DBUS_TYPE_OBJECT_PATH)
+ return;
+ EINA_ARRAY_ITER_NEXT(array->array, i, item, iterator)
+ _e_connman_element_item_register(name, item);
+}
+
+static bool
+_e_connman_element_property_update(E_Connman_Element_Property *property, int type, void *data)
+{
+ int changed = 0;
+
+ if ((type == DBUS_TYPE_STRING || type == DBUS_TYPE_OBJECT_PATH) && data)
+ data = (char *)eina_stringshare_add(data);
+
+ if (property->type != type)
+ {
+ if (property->type)
+ DBG("property type changed from '%c' to '%c'\n",
+ property->type, type);
+ _e_connman_element_property_value_free(property);
+ memset(&property->value, 0, sizeof(property->value));
+ property->type = type;
+ changed = 1;
+ }
+
+ switch (type)
+ {
+ case DBUS_TYPE_BOOLEAN:
+ if (changed || property->value.boolean != (bool)(long)data)
+ {
+ property->value.boolean = (bool)(long)data;
+ changed = 1;
+ }
+ break;
+ case DBUS_TYPE_BYTE:
+ if (changed || property->value.byte != (unsigned char)(long)data)
+ {
+ property->value.byte = (unsigned char)(long)data;
+ changed = 1;
+ }
+ case DBUS_TYPE_UINT16:
+ if (changed || property->value.u16 != (unsigned short)(long)data)
+ {
+ property->value.u16 = (unsigned short)(long)data;
+ changed = 1;
+ }
+ break;
+ case DBUS_TYPE_UINT32:
+ if (changed || property->value.u32 != (unsigned int)(long)data)
+ {
+ property->value.u32 = (unsigned int)(long)data;
+ changed = 1;
+ }
+ break;
+ case DBUS_TYPE_STRING:
+ if (changed)
+ property->value.str = data;
+ else
+ {
+ if (property->value.str)
+ eina_stringshare_del(property->value.str);
+ if (property->value.str != data)
+ {
+ property->value.str = data;
+ changed = 1;
+ }
+ }
+ break;
+ case DBUS_TYPE_OBJECT_PATH:
+ if (changed)
+ property->value.path = data;
+ else
+ {
+ if (property->value.path)
+ eina_stringshare_del(property->value.path);
+ if (property->value.path != data)
+ {
+ property->value.path = data;
+ changed = 1;
+ }
+ }
+ break;
+ case DBUS_TYPE_ARRAY:
+ if (!changed)
+ if (property->value.array)
+ {
+ _e_connman_element_array_free(property->value.array, data);
+ _e_connman_element_objects_array_register(data, property->name);
+ }
+ property->value.array = data;
+ changed = 1;
+ break;
+ default:
+ ERR("don't know how to update property type %c (%d)\n", type, type);
+ }
+
+ return changed;
+}
+
+static E_Connman_Element_Property *
+_e_connman_element_property_new(const char *name, int type, void *data)
+{
+ E_Connman_Element_Property *property;
+
+ property = calloc(1, sizeof(*property));
+ if (!property)
+ {
+ eina_stringshare_del(name);
+ ERR("could not allocate property: %s\n", strerror(errno));
+ return NULL;
+ }
+
+ property->name = name;
+ _e_connman_element_property_update(property, type, data);
+ return property;
+}
+
+static void
+_e_connman_element_property_free(E_Connman_Element_Property *property)
+{
+ _e_connman_element_property_value_free(property);
+ eina_stringshare_del(property->name);
+ free(property);
+}
+
+/***********************************************************************
+ * Element
+ ***********************************************************************/
+unsigned char *
+e_connman_element_bytes_array_get_stringshared(const E_Connman_Element *element, const char *property, unsigned int *count)
+{
+ Eina_Array_Iterator iterator;
+ E_Connman_Array *array;
+ unsigned char *ret, *p;
+ unsigned int i;
+ void *item;
+
+ EINA_SAFETY_ON_NULL_RETURN_VAL(element, NULL);
+ EINA_SAFETY_ON_NULL_RETURN_VAL(property, NULL);
+ EINA_SAFETY_ON_NULL_RETURN_VAL(count, NULL);
+
+ *count = 0;
+
+ if (!e_connman_element_property_get_stringshared
+ (element, property, NULL, &array))
+ return NULL;
+
+ if ((!array) || (!(array->array)))
+ return NULL;
+
+ *count = eina_array_count_get(array->array);
+ ret = malloc(*count * sizeof(unsigned char));
+ if (!ret)
+ {
+ ERR("could not allocate return array of %d bytes: %s\n",
+ *count, strerror(errno));
+ return NULL;
+ }
+ p = ret;
+
+ EINA_ARRAY_ITER_NEXT(array->array, i, item, iterator)
+ {
+ *p = (unsigned char)(long)item;
+ p++;
+ }
+ return ret;
+}
+
+bool
+e_connman_element_objects_array_get_stringshared(const E_Connman_Element *element, const char *property, unsigned int *count, E_Connman_Element ***elements)
+{
+ E_Connman_Element **ret, **p;
+ Eina_Array_Iterator iterator;
+ E_Connman_Array *array;
+ unsigned int i;
+ int type;
+ void *item;
+
+ EINA_SAFETY_ON_NULL_RETURN_VAL(element, 0);
+ EINA_SAFETY_ON_NULL_RETURN_VAL(property, 0);
+ EINA_SAFETY_ON_NULL_RETURN_VAL(count, 0);
+ EINA_SAFETY_ON_NULL_RETURN_VAL(elements, 0);
+
+ *count = 0;
+ *elements = NULL;
+
+ if (!e_connman_element_property_get_stringshared
+ (element, property, &type, &array))
+ return 0;
+
+ if (type != DBUS_TYPE_ARRAY)
+ {
+ ERR("property %s is not an array!\n", property);
+ return 0;
+ }
+
+ if ((!array) || (!array->array) || (array->type == DBUS_TYPE_INVALID))
+ return 0;
+
+ if (array->type != DBUS_TYPE_OBJECT_PATH)
+ {
+ ERR("property %s is not an array of object paths!\n", property);
+ return 0;
+ }
+
+ *count = eina_array_count_get(array->array);
+ ret = malloc(*count * sizeof(E_Connman_Element *));
+ if (!ret)
+ {
+ ERR("could not allocate return array of %d elements: %s\n",
+ *count, strerror(errno));
+ *count = 0;
+ return 0;
+ }
+ p = ret;
+
+ EINA_ARRAY_ITER_NEXT(array->array, i, item, iterator)
+ {
+ E_Connman_Element *e = e_connman_element_get(item);
+ if (!e)
+ continue;
+ *p = e;
+ p++;
+ }
+ *count = p - ret;
+ *elements = ret;
+ return 1;
+}
+
+void
+_e_connman_element_array_print(FILE *fp, E_Connman_Array *array)
+{
+ Eina_Array_Iterator iterator;
+ unsigned int i;
+ void *item;
+
+ if (!array)
+ return;
+
+ switch (array->type)
+ {
+ case DBUS_TYPE_OBJECT_PATH:
+ EINA_ARRAY_ITER_NEXT(array->array, i, item, iterator)
+ fprintf(fp, "\"%s\", ", (const char *)item);
+ break;
+ case DBUS_TYPE_BYTE:
+ EINA_ARRAY_ITER_NEXT(array->array, i, item, iterator)
+ fprintf(fp, "%#02hhx (\"%c\"), ", (unsigned char)(long)item,
+ (unsigned char)(long)item);
+ break;
+ case DBUS_TYPE_INVALID:
+ break;
+ default:
+ fprintf(fp, "<UNKNOWN ARRAY TYPE '%c'>", array->type);
+ }
+}
+
+/**
+ * Print element to file descriptor.
+ */
+void
+e_connman_element_print(FILE *fp, const E_Connman_Element *element)
+{
+ const E_Connman_Element_Property *p;
+
+ EINA_SAFETY_ON_NULL_RETURN(fp);
+ if (!element)
+ {
+ fputs("ERROR: no element to print\n", fp);
+ return;
+ }
+
+ fprintf(fp,
+ "Element %p: %s [%s]\n"
+ "\tProperties:\n",
+ element, element->path, element->interface);
+
+ EINA_INLIST_FOREACH(element->props, p)
+ {
+ fprintf(fp, "\t\t%s (%c) = ", p->name, p->type);
+
+ switch (p->type)
+ {
+ case DBUS_TYPE_STRING:
+ fprintf(fp, "\"%s\"", p->value.str);
+ break;
+ case DBUS_TYPE_OBJECT_PATH:
+ fprintf(fp, "\"%s\"", p->value.path);
+ break;
+ case DBUS_TYPE_BOOLEAN:
+ fprintf(fp, "%hhu", p->value.boolean);
+ break;
+ case DBUS_TYPE_BYTE:
+ fprintf(fp, "%#02hhx (%d), ", p->value.byte, p->value.byte);
+ break;
+ case DBUS_TYPE_UINT16:
+ fprintf(fp, "%hu", p->value.u16);
+ break;
+ case DBUS_TYPE_UINT32:
+ fprintf(fp, "%u", p->value.u32);
+ break;
+ case DBUS_TYPE_ARRAY:
+ _e_connman_element_array_print(fp, p->value.array);
+ break;
+ default:
+ fputs("don't know how to print type", fp);
+ }
+
+ fputc('\n', fp);
+ }
+}
+
+static E_Connman_Element *
+e_connman_element_new(const char *path, const char *interface)
+{
+ E_Connman_Element *element;
+
+ element = calloc(1, sizeof(*element));
+ if (!element)
+ {
+ ERR("could not allocate element: %s\n", strerror(errno));
+ return NULL;
+ }
+
+ element->path = eina_stringshare_add(path);
+ element->interface = eina_stringshare_ref(interface);
+ element->_references = 1;
+
+ return element;
+}
+
+static inline int
+_stringshare_replace(const char **str, const char *new)
+{
+ new = eina_stringshare_add(new);
+ eina_stringshare_del(*str);
+ if (*str == new)
+ return 0;
+ *str = new;
+ return 1;
+}
+
+static void
+e_connman_element_extra_properties_free(E_Connman_Element *element)
+{
+ while (element->props)
+ {
+ E_Connman_Element_Property *prop;
+ prop = (E_Connman_Element_Property *)element->props;
+ element->props = element->props->next;
+ _e_connman_element_property_free(prop);
+ }
+}
+
+static void
+e_connman_element_free(E_Connman_Element *element)
+{
+ if (element->_idler.changed)
+ ecore_idler_del(element->_idler.changed);
+
+ while (element->_listeners)
+ {
+ E_Connman_Element_Listener *l = (void *)element->_listeners;
+ element->_listeners = eina_inlist_remove
+ (element->_listeners, element->_listeners);
+
+ if (l->free_data) l->free_data(l->data);
+ free(l);
+ }
+
+ e_connman_element_pending_cancel_and_free(&element->_pending.properties_get);
+ e_connman_element_pending_cancel_and_free(&element->_pending.property_set);
+ e_connman_element_pending_cancel_and_free(&element->_pending.network_create);
+ e_connman_element_pending_cancel_and_free(&element->_pending.network_remove);
+ e_connman_element_pending_cancel_and_free(&element->_pending.network_connect);
+ e_connman_element_pending_cancel_and_free(&element->_pending.network_disconnect);
+ e_connman_element_pending_cancel_and_free(&element->_pending.agent_register);
+ e_connman_element_pending_cancel_and_free(&element->_pending.agent_unregister);
+ e_connman_element_pending_cancel_and_free(&element->_pending.device_propose_scan);
+
+ e_connman_element_extra_properties_free(element);
+ eina_stringshare_del(element->interface);
+ eina_stringshare_del(element->path);
+ free(element);
+}
+
+/**
+ * Add reference to element.
+ */
+int
+e_connman_element_ref(E_Connman_Element *element)
+{
+ EINA_SAFETY_ON_NULL_RETURN_VAL(element, 0);
+ return ++element->_references;
+}
+
+/**
+ * Remove reference from element.
+ *
+ * If reference count drops to 0 element will be freed.
+ */
+int
+e_connman_element_unref(E_Connman_Element *element)
+{
+ int i;
+ EINA_SAFETY_ON_NULL_RETURN_VAL(element, 0);
+
+ i = --element->_references;
+ if (i == 0)
+ e_connman_element_free(element);
+ else if (i < 0)
+ ERR("element %p references %d < 0\n", element, i);
+ return i;
+}
+
+/**
+ * Send message with callbacks set to work with connman elements.
+ *
+ * If this call fails (returns 0), pending callbacks will not be called,
+ * not even with error messages.
+ *
+ * @return 1 on success, 0 on failure.
+ */
+bool
+e_connman_element_message_send(E_Connman_Element *element, const char *method_name, E_DBus_Method_Return_Cb cb, DBusMessage *msg, Eina_Inlist **pending, E_DBus_Method_Return_Cb user_cb, const void *user_data)
+{
+ E_Connman_Element_Call_Data *data;
+ E_Connman_Element_Pending *p;
+
+ EINA_SAFETY_ON_NULL_RETURN_VAL(element, 0);
+ EINA_SAFETY_ON_NULL_RETURN_VAL(method_name, 0);
+ EINA_SAFETY_ON_NULL_RETURN_VAL(pending, 0);
+ EINA_SAFETY_ON_NULL_RETURN_VAL(msg, 0);
+
+ data = malloc(sizeof(*data));
+ if (!data)
+ {
+ ERR("could not alloc e_connman_element_call_data: %s\n",
+ strerror(errno));
+ dbus_message_unref(msg);
+ return 0;
+ }
+
+ p = malloc(sizeof(*p));
+ if (!p)
+ {
+ ERR("could not alloc E_Connman_Element_Pending: %s\n",
+ strerror(errno));
+ free(data);
+ dbus_message_unref(msg);
+ return 0;
+ }
+
+ data->element = element;
+ data->cb = cb;
+ data->pending = p;
+ data->p_list = pending;
+ p->user_cb = user_cb;
+ p->user_data = (void *)user_data;
+ p->data = data;
+ p->pending = e_dbus_message_send
+ (e_connman_conn, msg, e_connman_element_call_dispatch_and_free, -1, data);
+ dbus_message_unref(msg);
+
+ if (p->pending)
+ {
+ *pending = eina_inlist_append(*pending, EINA_INLIST_GET(p));
+ return 1;
+ }
+ else
+ {
+ ERR("failed to call %s (obj=%s, path=%s, iface=%s)\n",
+ method_name, e_connman_system_bus_name_get(),
+ element->path, element->interface);
+ free(data);
+ free(p);
+ return 0;
+ }
+}
+
+bool
+e_connman_element_call_full(E_Connman_Element *element, const char *method_name, E_DBus_Method_Return_Cb cb, Eina_Inlist **pending, E_DBus_Method_Return_Cb user_cb, const void *user_data)
+{
+ DBusMessage *msg;
+
+ EINA_SAFETY_ON_NULL_RETURN_VAL(element, 0);
+ EINA_SAFETY_ON_NULL_RETURN_VAL(method_name, 0);
+ EINA_SAFETY_ON_NULL_RETURN_VAL(pending, 0);
+
+ msg = dbus_message_new_method_call
+ (e_connman_system_bus_name_get(), element->path, element->interface,
+ method_name);
+
+ return e_connman_element_message_send
+ (element, method_name, cb, msg, pending, user_cb, user_data);
+}
+
+static bool
+_e_connman_element_property_value_add(E_Connman_Element *element, const char *name, int type, void *value)
+{
+ E_Connman_Element_Property *p;
+
+ name = eina_stringshare_add(name);
+ EINA_INLIST_FOREACH(element->props, p)
+ {
+ if (p->name == name)
+ {
+ eina_stringshare_del(name);
+ return _e_connman_element_property_update(p, type, value);
+ }
+ }
+
+ p = _e_connman_element_property_new(name, type, value);
+ if (!p)
+ {
+ ERR("could not create property %s (%c)\n", name, type);
+ return 0;
+ }
+
+ element->props = eina_inlist_append(element->props, EINA_INLIST_GET(p));
+ return 1;
+}
+
+static E_Connman_Array *
+_e_connman_element_iter_get_array(DBusMessageIter *itr, const char *key)
+{
+ E_Connman_Array *array;
+ DBusMessageIter e_itr;
+
+ array = malloc(sizeof(E_Connman_Array));
+ if (!array)
+ {
+ ERR("could not create new e_connman array.\n");
+ return NULL;
+ }
+ array->array = eina_array_new(16);
+ if (!(array->array))
+ {
+ ERR("could not create new eina array.\n");
+ free(array);
+ return NULL;
+ }
+
+ dbus_message_iter_recurse(itr, &e_itr);
+ array->type = dbus_message_iter_get_arg_type(&e_itr);
+ do
+ {
+ switch (array->type)
+ {
+ case DBUS_TYPE_INVALID:
+ break;
+ case DBUS_TYPE_OBJECT_PATH:
+ {
+ const char *path;
+
+ dbus_message_iter_get_basic(&e_itr, &path);
+ path = eina_stringshare_add(path);
+ eina_array_push(array->array, path);
+ _e_connman_element_item_register(key, path);
+ }
+ break;
+ case DBUS_TYPE_BYTE:
+ {
+ unsigned char byte;
+ dbus_message_iter_get_basic(&e_itr, &byte);
+ eina_array_push(array->array, (void *)(long)byte);
+ }
+ break;
+ default:
+ ERR("don't know how to get property type %c (%d)\n",
+ array->type, array->type);
+ }
+ }
+ while (dbus_message_iter_next(&e_itr));
+ return array;
+}
+
+static void
+_e_connman_element_get_properties_callback(void *user_data, DBusMessage *msg, DBusError *err)
+{
+ E_Connman_Element *element = user_data;
+ DBusMessageIter itr, s_itr;
+ int t, changed;
+
+ DBG("get_properties msg=%p\n", msg);
+
+ if (!_dbus_callback_check_and_init(msg, &itr, err))
+ return;
+
+ t = dbus_message_iter_get_arg_type(&itr);
+ if (!_dbus_iter_type_check(t, DBUS_TYPE_ARRAY))
+ return;
+
+ changed = 0;
+ dbus_message_iter_recurse(&itr, &s_itr);
+ do
+ {
+ DBusMessageIter e_itr, v_itr;
+ const char *key;
+ void *value;
+ int r;
+
+ t = dbus_message_iter_get_arg_type(&s_itr);
+ if (!_dbus_iter_type_check(t, DBUS_TYPE_DICT_ENTRY))
+ continue;
+
+ dbus_message_iter_recurse(&s_itr, &e_itr);
+
+ t = dbus_message_iter_get_arg_type(&e_itr);
+ if (!_dbus_iter_type_check(t, DBUS_TYPE_STRING))
+ continue;
+
+ dbus_message_iter_get_basic(&e_itr, &key);
+ dbus_message_iter_next(&e_itr);
+ t = dbus_message_iter_get_arg_type(&e_itr);
+ if (!_dbus_iter_type_check(t, DBUS_TYPE_VARIANT))
+ continue;
+
+ dbus_message_iter_recurse(&e_itr, &v_itr);
+ t = dbus_message_iter_get_arg_type(&v_itr);
+ if (t == DBUS_TYPE_ARRAY)
+ value = _e_connman_element_iter_get_array(&v_itr, key);
+ else if (t != DBUS_TYPE_INVALID)
+ dbus_message_iter_get_basic(&v_itr, &value);
+ r = _e_connman_element_property_value_add(element, key, t, value);
+ if (r < 0)
+ ERR("failed to add property value %s (%c)\n", key, t);
+ else if (r == 1)
+ {
+ INF("property value changed %s (%c)\n", key, t);
+ changed = 1;
+ }
+ }
+ while (dbus_message_iter_next(&s_itr));
+
+ if (changed)
+ _e_connman_element_listeners_call(element);
+}
+
+/**
+ * Sync element properties with server.
+ *
+ * Call method GetProperties() at the given element on server in order to sync
+ * them.
+ *
+ * @param element to call method on server.
+ * @param cb function to call when server replies or some error happens.
+ * @param data data to give to cb when it is called.
+ *
+ * @return 1 on success, 0 otherwise.
+ */
+bool
+e_connman_element_sync_properties_full(E_Connman_Element *element, E_DBus_Method_Return_Cb cb, const void *data)
+{
+ const char name[] = "GetProperties";
+
+ EINA_SAFETY_ON_NULL_RETURN_VAL(element, 0);
+ return e_connman_element_call_full
+ (element, name, _e_connman_element_get_properties_callback,
+ &element->_pending.properties_get, cb, data);
+}
+
+/**
+ * Sync element properties with server, simple version.
+ *
+ * Call method GetProperties() at the given element on server in order to sync
+ * them. This is the simple version and there is no check of server reply
+ * for errors.
+ *
+ * @param element to call method on server.
+ *
+ * @return 1 on success, 0 otherwise.
+ */
+bool
+e_connman_element_properties_sync(E_Connman_Element *element)
+{
+ EINA_SAFETY_ON_NULL_RETURN_VAL(element, 0);
+ return e_connman_element_sync_properties_full(element, NULL, NULL);
+}
+
+/**
+ * Call method SetProperty(prop, value) at the given element on server.
+ *
+ * This is a server call, not local, so it may fail and in that case
+ * no property is updated locally. If the value was set the event
+ * E_CONNMAN_EVENT_ELEMENT_UPDATED will be added to main loop.
+ *
+ * @param element to call method on server.
+ * @param prop property name.
+ * @param type DBus type to use for value.
+ * @param value pointer to value, just like regular DBus, see
+ * dbus_message_iter_append_basic().
+ * @param cb function to call when server replies or some error happens.
+ * @param data data to give to cb when it is called.
+ *
+ * @return 1 on success, 0 otherwise.
+ */
+bool
+e_connman_element_property_set_full(E_Connman_Element *element, const char *prop, int type, const void *value, E_DBus_Method_Return_Cb cb, const void *data)
+{
+ const char name[] = "SetProperty";
+ char typestr[2];
+ DBusMessage *msg;
+
+ EINA_SAFETY_ON_NULL_RETURN_VAL(element, 0);
+ EINA_SAFETY_ON_NULL_RETURN_VAL(prop, 0);
+
+ msg = dbus_message_new_method_call
+ (e_connman_system_bus_name_get(), element->path, element->interface, name);
+
+ if (!msg)
+ return 0;
+
+ DBusMessageIter itr, v;
+ dbus_message_iter_init_append(msg, &itr);
+ dbus_message_iter_append_basic(&itr, DBUS_TYPE_STRING, &prop);
+
+ typestr[0] = type;
+ typestr[1] = '\0';
+ dbus_message_iter_open_container(&itr, DBUS_TYPE_VARIANT, typestr, &v);
+ if ((type == DBUS_TYPE_STRING) || (type == DBUS_TYPE_OBJECT_PATH))
+ dbus_message_iter_append_basic(&v, type, &value);
+ else
+ dbus_message_iter_append_basic(&v, type, value);
+ dbus_message_iter_close_container(&itr, &v);
+
+ return e_connman_element_message_send
+ (element, name, NULL, msg, &element->_pending.property_set, cb, data);
+}
+
+/**
+ * Call method SetProperty(prop, value) at the given element on server.
+ *
+ * This is the simple version and there is no check of server reply
+ * for errors.
+ *
+ * @param element to call method on server.
+ * @param prop property name.
+ * @param type DBus type to use for value.
+ * @param value pointer to value, just like regular DBus, see
+ * dbus_message_iter_append_basic().
+ *
+ * @return 1 on success, 0 otherwise.
+ */
+bool
+e_connman_element_property_set(E_Connman_Element *element, const char *prop, int type, const void *value)
+{
+ EINA_SAFETY_ON_NULL_RETURN_VAL(element, 0);
+ EINA_SAFETY_ON_NULL_RETURN_VAL(prop, 0);
+ return e_connman_element_property_set_full
+ (element, prop, type, value, NULL, NULL);
+}
+
+bool
+e_connman_element_call_with_path(E_Connman_Element *element, const char *method_name, const char *string, E_DBus_Method_Return_Cb cb, Eina_Inlist **pending, E_DBus_Method_Return_Cb user_cb, const void *user_data)
+{
+ DBusMessageIter itr;
+ DBusMessage *msg;
+
+ EINA_SAFETY_ON_NULL_RETURN_VAL(element, 0);
+ EINA_SAFETY_ON_NULL_RETURN_VAL(method_name, 0);
+ EINA_SAFETY_ON_NULL_RETURN_VAL(string, 0);
+ EINA_SAFETY_ON_NULL_RETURN_VAL(pending, 0);
+
+ msg = dbus_message_new_method_call
+ (e_connman_system_bus_name_get(), element->path, element->interface,
+ method_name);
+
+ if (!msg)
+ return 0;
+
+ dbus_message_iter_init_append(msg, &itr);
+ dbus_message_iter_append_basic(&itr, DBUS_TYPE_OBJECT_PATH, &string);
+
+ return e_connman_element_message_send
+ (element, method_name, cb, msg, pending, user_cb, user_data);
+}
+
+/**
+ * Get property type.
+ *
+ * If zero is returned, then this call failed and parameter-returned
+ * values shall be considered invalid.
+ *
+ * @param element which element to get the property
+ * @param name property name, must be previously stringshared
+ * @param type will contain the value type.
+ *
+ * @return 1 on success, 0 otherwise.
+ */
+bool
+e_connman_element_property_type_get_stringshared(const E_Connman_Element *element, const char *name, int *type)
+{
+ const E_Connman_Element_Property *p;
+
+ EINA_SAFETY_ON_NULL_RETURN_VAL(element, 0);
+ EINA_SAFETY_ON_NULL_RETURN_VAL(name, 0);
+ EINA_SAFETY_ON_NULL_RETURN_VAL(type, 0);
+
+ EINA_INLIST_FOREACH(element->props, p)
+ {
+ if (p->name == name)
+ {
+ *type = p->type;
+ return 1;
+ }
+ }
+
+ WRN("element %s (%p) has no property with name \"%s\".\n",
+ element->path, element, name);
+ return 0;
+}
+
+/**
+ * Get property type.
+ *
+ * If zero is returned, then this call failed and parameter-returned
+ * values shall be considered invalid.
+ *
+ * @param element which element to get the property
+ * @param name property name
+ * @param type will contain the value type.
+ *
+ * @return 1 on success, 0 otherwise.
+ */
+bool
+e_connman_element_property_type_get(const E_Connman_Element *element, const char *name, int *type)
+{
+ bool ret;
+ name = eina_stringshare_add(name);
+ ret = e_connman_element_property_type_get_stringshared(element, name, type);
+ eina_stringshare_del(name);
+ return ret;
+}
+
+void
+e_connman_element_list_properties(const E_Connman_Element *element, bool (*cb)(void *data, const E_Connman_Element *element, const char *name, int type, const void *value), const void *data)
+{
+ const E_Connman_Element_Property *p;
+
+ EINA_SAFETY_ON_NULL_RETURN(element);
+ EINA_SAFETY_ON_NULL_RETURN(cb);
+
+ EINA_INLIST_FOREACH(element->props, p)
+ {
+ const void *value = NULL;
+
+ switch (p->type)
+ {
+ case DBUS_TYPE_STRING:
+ value = &p->value.str;
+ break;
+ case DBUS_TYPE_OBJECT_PATH:
+ value = &p->value.path;
+ break;
+ case DBUS_TYPE_BOOLEAN:
+ value = (void *)p->value.boolean;
+ break;
+ case DBUS_TYPE_UINT16:
+ value = &p->value.u16;
+ break;
+ case DBUS_TYPE_UINT32:
+ value = &p->value.u32;
+ break;
+ default:
+ ERR("unsupported type %c\n", p->type);
+ }
+
+ if (!cb((void *)data, element, p->name, p->type, value))
+ return;
+ }
+}
+
+/**
+ * Get property value given its name.
+ *
+ * This will look into properties, to find the property.
+ * If no property is found then 0 is returned.
+ *
+ * If zero is returned, then this call failed and parameter-returned
+ * values shall be considered invalid.
+ *
+ * @param element which element to get the property
+ * @param name property name, must be previously stringshared
+ * @param type if provided it will contain the value type.
+ * @param value where to store the property value, must be a pointer to the
+ * exact type, (bool *) for booleans, (char **) for strings, and so on.
+ *
+ * @return 1 on success, 0 otherwise.
+ */
+bool
+e_connman_element_property_get_stringshared(const E_Connman_Element *element, const char *name, int *type, void *value)
+{
+ const E_Connman_Element_Property *p;
+
+ EINA_SAFETY_ON_NULL_RETURN_VAL(element, 0);
+ EINA_SAFETY_ON_NULL_RETURN_VAL(name, 0);
+ EINA_SAFETY_ON_NULL_RETURN_VAL(value, 0);
+
+ EINA_INLIST_FOREACH(element->props, p)
+ {
+ if (p->name != name)
+ continue;
+
+ if (type) *type = p->type;
+
+ switch (p->type)
+ {
+ case DBUS_TYPE_BOOLEAN:
+ *(bool *)value = p->value.boolean;
+ return 1;
+ case DBUS_TYPE_BYTE:
+ *(unsigned char *)value = p->value.byte;
+ return 1;
+ case DBUS_TYPE_UINT16:
+ *(unsigned short *)value = p->value.u16;
+ return 1;
+ case DBUS_TYPE_UINT32:
+ *(unsigned int *)value = p->value.u32;
+ return 1;
+ case DBUS_TYPE_STRING:
+ *(const char **)value = p->value.str;
+ return 1;
+ case DBUS_TYPE_OBJECT_PATH:
+ *(const char **)value = p->value.path;
+ return 1;
+ case DBUS_TYPE_ARRAY:
+ *(E_Connman_Array **)value = p->value.array;
+ return 1;
+ default:
+ ERR("don't know how to get property type %c (%d)\n",
+ p->type, p->type);
+ return 0;
+ }
+ }
+
+ WRN("element %s (%p) has no property with name \"%s\".\n",
+ element->path, element, name);
+ return 0;
+}
+
+/**
+ * Get property value given its name.
+ *
+ * This will look into properties, to find the property.
+ * If no property is found then 0 is returned.
+ *
+ * If zero is returned, then this call failed and parameter-returned
+ * values shall be considered invalid.
+ *
+ * @param element which element to get the property
+ * @param name property name
+ * @param type if provided it will contain the value type.
+ * @param value where to store the property value, must be a pointer to the
+ * exact type, (bool *) for booleans, (char **) for strings, and so on.
+ *
+ * @return 1 on success, 0 otherwise.
+ */
+bool
+e_connman_element_property_get(const E_Connman_Element *element, const char *name, int *type, void *value)
+{
+ bool ret;
+ name = eina_stringshare_add(name);
+ ret = e_connman_element_property_get_stringshared
+ (element, name, type, value);
+ eina_stringshare_del(name);
+ return ret;
+}
+
+
+struct e_connman_elements_for_each_data
+{
+ Eina_Hash_Foreach cb;
+ void *data;
+};
+
+Eina_Bool
+_e_connman_elements_for_each(Eina_Hash *hash, const char *key, void *data, void *fdata)
+{
+ struct e_connman_elements_for_each_data *each_data = fdata;
+
+ each_data->cb(elements, key, data, each_data->data);
+ return 1;
+}
+
+/**
+ * Call the given function for each existing element.
+ *
+ * @param cb function to call for each element. It will get as parameters,
+ * in order: the element pointer and the given @a user_data.
+ * @param user_data data to give to @a cb for each element.
+ */
+void
+e_connman_elements_for_each(Eina_Hash_Foreach cb, const void *user_data)
+{
+ struct e_connman_elements_for_each_data data = {cb, (void *)user_data};
+
+ EINA_SAFETY_ON_NULL_RETURN(cb);
+
+ eina_hash_foreach(elements, (Eina_Hash_Foreach) _e_connman_elements_for_each,
+ &data);
+}
+
+static bool
+_e_connman_elements_get_allocate(unsigned int *count, E_Connman_Element ***p_elements)
+{
+ *count = eina_hash_population(elements);
+ if (*count == 0)
+ {
+ *p_elements = NULL;
+ return 1;
+ }
+
+ *p_elements = malloc(*count * sizeof(E_Connman_Element *));
+ if (!*p_elements)
+ {
+ ERR("could not allocate return array of %d elements: %s\n",
+ *count, strerror(errno));
+ *count = 0;
+ return 0;
+ }
+ return 1;
+}
+
+Eina_Bool
+_e_connman_elements_get_all(Eina_Hash *hash, const char *key, void *data, void *fdata)
+{
+ E_Connman_Element *element = data;
+ E_Connman_Element ***p_ret = fdata;
+
+ **p_ret = element;
+ (*p_ret)++;
+ return 1;
+}
+
+/**
+ * Get all known elements.
+ *
+ * No reference is added to these elements, since there are no threads
+ * in the system, you are free to add references yourself right after
+ * the return of this call without race condition, elements by the
+ * system (ie: elementRemoved signal)could only be touched on the next
+ * main loop iteration.
+ *
+ * @param count return the number of elements in array.
+ * @param p_elements array with all elements, these are not referenced
+ * and in no particular order, just set if return is 1.
+ *
+ * @return 1 on success, 0 otherwise.
+ */
+bool
+e_connman_elements_get_all(unsigned int *count, E_Connman_Element ***p_elements)
+{
+ E_Connman_Element **p;
+
+ EINA_SAFETY_ON_NULL_RETURN_VAL(count, 0);
+ EINA_SAFETY_ON_NULL_RETURN_VAL(p_elements, 0);
+
+ if (!_e_connman_elements_get_allocate(count, p_elements))
+ return 0;
+ p = *p_elements;
+ eina_hash_foreach(elements, (Eina_Hash_Foreach) _e_connman_elements_get_all,
+ &p);
+ return 1;
+}
+
+struct e_connman_elements_get_all_str_data
+{
+ E_Connman_Element **elements;
+ int count;
+ const char *str;
+};
+
+Eina_Bool
+_e_connman_elements_get_all_type(Eina_Hash *hash, const char *key, void *e, void *user_data)
+{
+ struct e_connman_elements_get_all_str_data *data = user_data;
+ E_Connman_Element *element = e;
+
+ if ((data->str) && (element->interface != data->str))
+ return 1;
+
+ data->elements[data->count] = element;
+ data->count++;
+ return 1;
+}
+
+/**
+ * Get all known elements of type.
+ *
+ * No reference is added to these elements, since there are no threads
+ * in the system, you are free to add references yourself right after
+ * the return of this call without race condition, elements by the
+ * system (ie: ElementRemoved signal) could only be touched on the next
+ * main loop iteration.
+ *
+ * @param type type to filter, or NULL to get all.
+ * @param count return the number of elements in array.
+ * @param p_elements array with all elements, these are not referenced
+ * and in no particular order, just set if return is 1.
+ *
+ * @return 1 on success, 0 otherwise.
+ *
+ * @see e_connman_elements_get_all()
+ */
+bool
+e_connman_elements_get_all_type(const char *type, unsigned int *count, E_Connman_Element ***p_elements)
+{
+ struct e_connman_elements_get_all_str_data data;
+
+ EINA_SAFETY_ON_NULL_RETURN_VAL(count, 0);
+ EINA_SAFETY_ON_NULL_RETURN_VAL(p_elements, 0);
+
+ if (!_e_connman_elements_get_allocate(count, p_elements))
+ return 0;
+
+ data.elements = *p_elements;
+ data.count = 0;
+ data.str = eina_stringshare_add(type);
+ eina_hash_foreach(elements,
+ (Eina_Hash_Foreach) _e_connman_elements_get_all_type,
+ &data);
+
+ eina_stringshare_del(data.str);
+ *count = data.count;
+ return 1;
+}
+
+/**
+ * Get the element registered at given path.
+ *
+ * @param path the path to query for registered object.
+ *
+ * @return element pointer if found, NULL otherwise. No references are added.
+ */
+E_Connman_Element *
+e_connman_element_get(const char *path)
+{
+ E_Connman_Element *element;
+
+ EINA_SAFETY_ON_NULL_RETURN_VAL(path, NULL);
+ element = eina_hash_find(elements, path);
+
+ return element;
+}
+
+static void
+_e_connman_element_property_changed_callback(void *data, DBusMessage *msg)
+{
+ E_Connman_Element *element = (E_Connman_Element *)data;
+ DBusMessageIter itr, v_itr;
+ int t, r, changed = 0;
+ const char *name;
+ void *value;
+
+ DBG("Property changed in element %s\n", element->path);
+
+ if (!_dbus_callback_check_and_init(msg, &itr, NULL))
+ return;
+
+ t = dbus_message_iter_get_arg_type(&itr);
+ if (!_dbus_iter_type_check(t, DBUS_TYPE_STRING))
+ ERR("missing name in property changed signal\n");
+ dbus_message_iter_get_basic(&itr, &name);
+
+ dbus_message_iter_next(&itr);
+ t = dbus_message_iter_get_arg_type(&itr);
+ if (!_dbus_iter_type_check(t, DBUS_TYPE_VARIANT))
+ ERR("missing value in property changed signal\n");
+ dbus_message_iter_recurse(&itr, &v_itr);
+ t = dbus_message_iter_get_arg_type(&v_itr);
+
+ if (t == DBUS_TYPE_ARRAY)
+ value = _e_connman_element_iter_get_array(&v_itr, name);
+ else if (t != DBUS_TYPE_INVALID)
+ dbus_message_iter_get_basic(&v_itr, &value);
+ r = _e_connman_element_property_value_add(element, name, t, value);
+ if (r < 0)
+ ERR("failed to add property value %s (%c)\n", name, t);
+ else if (r == 1)
+ {
+ INF("property value changed %s (%c)\n", name, t);
+ changed = 1;
+ }
+ if (changed)
+ _e_connman_element_listeners_call(element);
+}
+
+/**
+ * Register the given path, possible creating and element and return it.
+ *
+ * This will check if path is already registered, in that case the
+ * exiting element is returned. If it was not registered yet, a new
+ * element is created, registered and returned.
+ *
+ * This call will not add extra references to the object.
+ *
+ * @param path the path to register the element
+ *
+ * @return the registered object, no references are added.
+ */
+E_Connman_Element *
+e_connman_element_register(const char *path, const char *interface)
+{
+ E_Connman_Element *element;
+
+ EINA_SAFETY_ON_NULL_RETURN_VAL(path, NULL);
+ EINA_SAFETY_ON_NULL_RETURN_VAL(interface, NULL);
+
+ element = eina_hash_find(elements, path);
+ if (element)
+ return element;
+
+ element = e_connman_element_new(path, interface);
+ if (!element)
+ return NULL;
+
+ if (!eina_hash_add(elements, element->path, element))
+ {
+ ERR("could not add element %s to hash, delete it.\n", path);
+ e_connman_element_free(element);
+ return NULL;
+ }
+
+ element->signal_handler =
+ e_dbus_signal_handler_add
+ (e_connman_conn, e_connman_system_bus_name_get(),
+ element->path, element->interface, "PropertyChanged",
+ _e_connman_element_property_changed_callback, element);
+
+ e_connman_element_event_add(E_CONNMAN_EVENT_ELEMENT_ADD, element);
+
+ return element;
+}
+
+static void
+_e_connman_element_event_unregister_and_free(void *data, void *ev)
+{
+ E_Connman_Element *element = ev;
+ e_connman_element_unref(element);
+}
+
+static void
+_e_connman_element_unregister_internal(E_Connman_Element *element)
+{
+ if (element->signal_handler)
+ {
+ e_dbus_signal_handler_del(e_connman_conn, element->signal_handler);
+ element->signal_handler = NULL;
+ }
+
+ ecore_event_add(E_CONNMAN_EVENT_ELEMENT_DEL, element,
+ _e_connman_element_event_unregister_and_free, NULL);
+}
+
+/**
+ * Forget about the given element.
+ *
+ * This will remove the element from the pool of known objects, then
+ * add an E_CONNMAN_EVENT_ELEMENT_DEL and after that will unreference it,
+ * possible freeing it.
+ *
+ * @param element element to forget about. Its reference will be removed.
+ */
+void
+e_connman_element_unregister(E_Connman_Element *element)
+{
+ if (!element)
+ return;
+
+ if (elements)
+ eina_hash_del_by_key(elements, element->path);
+
+ _e_connman_element_unregister_internal(element);
+}
+
+/**
+ * Remove all known elements.
+ *
+ * This will remove all known elements but will NOT add any
+ * E_CONNMAN_EVENT_ELEMENT_DEL to main loop.
+ *
+ * This is just useful to make sure next e_connman_manager_sync_elements()
+ * will not leave any stale elements. This is unlikely to happen, as
+ * E_Connman is supposed to catch all required events to avoid stale elements.
+ */
+void
+e_connman_manager_clear_elements(void)
+{
+ e_connman_elements_shutdown();
+ e_connman_elements_init();
+}
+
+/**
+ * Creates elements hash.
+ *
+ * This has no init counter since its already guarded by other code.
+ * @internal
+ */
+void
+e_connman_elements_init(void)
+{
+ EINA_SAFETY_ON_FALSE_RETURN(elements == NULL);
+ elements =
+ eina_hash_string_superfast_new(EINA_FREE_CB
+ (_e_connman_element_unregister_internal));
+}
+
+void
+e_connman_elements_shutdown(void)
+{
+ EINA_SAFETY_ON_FALSE_RETURN(elements != NULL);
+ eina_hash_free(elements);
+ elements = NULL;
+}
+
+static inline bool
+_e_connman_element_is(const E_Connman_Element *element, const char *interface)
+{
+ return element->interface == interface;
+}
+
+bool
+e_connman_element_is_manager(const E_Connman_Element *element)
+{
+ EINA_SAFETY_ON_NULL_RETURN_VAL(element, 0);
+ return _e_connman_element_is(element, e_connman_iface_manager);
+}
+
+bool
+e_connman_element_is_device(const E_Connman_Element *element)
+{
+ EINA_SAFETY_ON_NULL_RETURN_VAL(element, 0);
+ return _e_connman_element_is(element, e_connman_iface_device);
+}
+
+bool
+e_connman_element_is_profile(const E_Connman_Element *element)
+{
+ EINA_SAFETY_ON_NULL_RETURN_VAL(element, 0);
+ return _e_connman_element_is(element, e_connman_iface_profile);
+}
+
+bool
+e_connman_element_is_connection(const E_Connman_Element *element)
+{
+ EINA_SAFETY_ON_NULL_RETURN_VAL(element, 0);
+ return _e_connman_element_is(element, e_connman_iface_connection);
+}
+
+bool
+e_connman_element_is_network(const E_Connman_Element *element)
+{
+ EINA_SAFETY_ON_NULL_RETURN_VAL(element, 0);
+ return _e_connman_element_is(element, e_connman_iface_network);
+}
--- /dev/null
+#include "e_connman_private.h"
+
+/**
+ * Get the element manager.
+ *
+ * @return element pointer if found, NULL otherwise.
+ */
+E_Connman_Element *
+e_connman_manager_get(void)
+{
+ return e_connman_element_get(manager_path);
+}
+
+/**
+ * Register new agent for handling user requests.
+ *
+ * Call method RegisterAgent(object) on server in order to
+ * register new agent for handling user requests.
+ *
+ * @param object_path object to be registered.
+ * @param cb function to call when server replies or some error happens.
+ * @param data data to give to cb when it is called.
+ *
+ * @return 1 on success, 0 otherwise.
+ */
+bool
+e_connman_manager_register_agent(const char *object_path, E_DBus_Method_Return_Cb cb, const void *data)
+{
+ const char name[] = "RegisterAgent";
+ E_Connman_Element *element;
+
+ EINA_SAFETY_ON_NULL_RETURN_VAL(object_path, 0);
+
+ element = e_connman_manager_get();
+ if (!element)
+ return 0;
+
+ return e_connman_element_call_with_path
+ (element, name, object_path, NULL,
+ &element->_pending.agent_register, cb, data);
+}
+
+/**
+ * Unregister an existing agent.
+ *
+ * Call method UnregisterAgent(object) on server in order to
+ * unregister an existing agent.
+ *
+ * @param object_path agent to be unregistered.
+ * @param cb function to call when server replies or some error happens.
+ * @param data data to give to cb when it is called.
+ *
+ * @return 1 on success, 0 otherwise.
+ */
+bool
+e_connman_manager_unregister_agent(const char *object_path, E_DBus_Method_Return_Cb cb, const void *data)
+{
+ const char name[] = "UnregisterAgent";
+ E_Connman_Element *element;
+
+ EINA_SAFETY_ON_NULL_RETURN_VAL(object_path, 0);
+
+ element = e_connman_manager_get();
+ if (!element)
+ return 0;
+
+ return e_connman_element_call_with_path
+ (element, name, object_path, NULL,
+ &element->_pending.agent_unregister, cb, data);
+}
+
+/**
+ * Get property "State" value.
+ *
+ * If this property isn't found then 0 is returned.
+ * If zero is returned, then this call failed and parameter-returned
+ * values shall be considered invalid.
+ *
+ * The global connection state of a system. Possible
+ * values are "online" if at least one connection exists
+ * and "offline" if no device is connected.
+ *
+ * In certain situations the state might change to
+ * the value "connected". This can only be seen if
+ * previously no connection was present.
+ *
+ * @param state where to store the property value, must be a pointer
+ * to string (const char **), it will not be allocated or
+ * copied and references will be valid until element changes,
+ * so copy it if you want to use it later.
+ *
+ * @return 1 on success, 0 otherwise.
+ */
+bool
+e_connman_manager_state_get(const char **state)
+{
+ E_Connman_Element *element;
+
+ EINA_SAFETY_ON_NULL_RETURN_VAL(state, 0);
+
+ element = e_connman_manager_get();
+ if (!element)
+ return 0;
+ return e_connman_element_property_get_stringshared
+ (element, e_connman_prop_state, NULL, state);
+}
+
+/**
+ * Get property "Policy" value.
+ *
+ * If this property isn't found then 0 is returned.
+ * If zero is returned, then this call failed and parameter-returned
+ * values shall be considered invalid.
+ *
+ * The global connection policy of a system. This
+ * allows to configure how connections are established
+ * and also when they are taken down again.
+ *
+ * Possible values are "single", "multiple" and "ask".
+ *
+ * For the single policy, the priority setting of the
+ * device defines which becomes the default connection
+ * when multiple are available.
+ *
+ * @param policy where to store the property value, must be a pointer
+ * to string (const char **), it will not be allocated or
+ * copied and references will be valid until element changes,
+ * so copy it if you want to use it later.
+ *
+ * @return 1 on success, 0 otherwise.
+ * @see e_connman_manager_policy_set()
+ */
+bool
+e_connman_manager_policy_get(const char **policy)
+{
+ E_Connman_Element *element;
+
+ EINA_SAFETY_ON_NULL_RETURN_VAL(policy, 0);
+
+ element = e_connman_manager_get();
+ if (!element)
+ return 0;
+ return e_connman_element_property_get_stringshared
+ (element, e_connman_prop_policy, NULL, policy);
+}
+
+/**
+ * Call method SetProperty("Policy", policy) at the given element on server.
+ *
+ * This is a server call, not local, so it may fail and in that case
+ * no property is updated locally. If the value was set the event
+ * E_CONNMAN_EVENT_ELEMENT_UPDATED will be added to main loop.
+ *
+ * The global connection policy of a system. This
+ * allows to configure how connections are established
+ * and also when they are taken down again.
+ *
+ * Possible values are "single", "multiple" and "ask".
+ *
+ * For the single policy, the priority setting of the
+ * device defines which becomes the default connection
+ * when multiple are available.
+ *
+ * @param policy value to set.
+ * @param cb function to call when server replies or some error happens.
+ * @param data data to give to cb when it is called.
+ *
+ * @return 1 on success, 0 otherwise.
+ * @see e_connman_manager_policy_get()
+ */
+bool
+e_connman_manager_policy_set(const char *policy, E_DBus_Method_Return_Cb cb, const void *data)
+{
+ E_Connman_Element *element;
+
+ EINA_SAFETY_ON_NULL_RETURN_VAL(policy, 0);
+
+ element = e_connman_manager_get();
+ if (!element)
+ return 0;
+
+ return e_connman_element_property_set_full
+ (element, e_connman_prop_policy, DBUS_TYPE_STRING, policy, cb, data);
+}
+
+/**
+ * Get property "OfflineMode" value.
+ *
+ * If this property isn't found then 0 is returned.
+ * If zero is returned, then this call failed and parameter-returned
+ * values shall be considered invalid.
+ *
+ * The offline mode indicates the global setting for
+ * switching all radios on or off. Changing offline mode
+ * to true results in powering down all devices. When
+ * leaving offline mode the individual policy of each
+ * device decides to switch the radio back on or not.
+ *
+ * During offline mode, it is still possible to switch
+ * certain technologies manually back on. For example
+ * the limited usage of WiFi or Bluetooth devices might
+ * be allowed in some situations.
+ *
+ * @param offline where to store the property value, must be a pointer
+ * to booleans (bool *).
+ *
+ * @return 1 on success, 0 otherwise.
+ * @see e_connman_manager_offline_mode_set()
+ */
+bool
+e_connman_manager_offline_mode_get(bool *offline)
+{
+ E_Connman_Element *element;
+
+ EINA_SAFETY_ON_NULL_RETURN_VAL(offline, 0);
+
+ element = e_connman_manager_get();
+ if (!element)
+ return 0;
+ return e_connman_element_property_get_stringshared
+ (element, e_connman_prop_offline_mode, NULL, offline);
+}
+
+/**
+ * Call method SetProperty("OfflineMode", offline) at the given element on server.
+ *
+ * This is a server call, not local, so it may fail and in that case
+ * no property is updated locally. If the value was set the event
+ * E_CONNMAN_EVENT_ELEMENT_UPDATED will be added to main loop.
+ *
+ * The offline mode indicates the global setting for
+ * switching all radios on or off. Changing offline mode
+ * to true results in powering down all devices. When
+ * leaving offline mode the individual policy of each
+ * device decides to switch the radio back on or not.
+ *
+ * During offline mode, it is still possible to switch
+ * certain technologies manually back on. For example
+ * the limited usage of WiFi or Bluetooth devices might
+ * be allowed in some situations.
+ *
+ * @param offline value to set.
+ * @param cb function to call when server replies or some error happens.
+ * @param data data to give to cb when it is called.
+ *
+ * @return 1 on success, 0 otherwise.
+ * @see e_connman_manager_offline_mode_get()
+ */
+bool
+e_connman_manager_offline_mode_set(bool offline, E_DBus_Method_Return_Cb cb, const void *data)
+{
+ E_Connman_Element *element = e_connman_manager_get();
+ if (!element)
+ return 0;
+ return e_connman_element_property_set_full
+ (element, e_connman_prop_offline_mode, DBUS_TYPE_BOOLEAN,
+ &offline, cb, data);
+}
+
+/**
+ * Get array of profile elements.
+ *
+ * @param count return the number of elements in array.
+ * @param p_elements array with all elements, these are not referenced
+ * and in no particular order, just set if return is 1.
+ *
+ * @return 1 on success, 0 otherwise.
+ */
+bool
+e_connman_manager_profiles_get(unsigned int *count, E_Connman_Element ***p_elements)
+{
+ E_Connman_Element *element;
+
+ EINA_SAFETY_ON_NULL_RETURN_VAL(count, 0);
+ EINA_SAFETY_ON_NULL_RETURN_VAL(p_elements, 0);
+
+ element = e_connman_manager_get();
+ if (!element)
+ return 0;
+ return e_connman_element_objects_array_get_stringshared
+ (element, e_connman_prop_profiles, count, p_elements);
+}
+
+/**
+ * Get array of device elements.
+ *
+ * @param count return the number of elements in array.
+ * @param p_elements array with all elements, these are not referenced
+ * and in no particular order, just set if return is 1.
+ *
+ * @return 1 on success, 0 otherwise.
+ */
+bool
+e_connman_manager_devices_get(unsigned int *count, E_Connman_Element ***p_elements)
+{
+ E_Connman_Element *element;
+
+ EINA_SAFETY_ON_NULL_RETURN_VAL(count, 0);
+ EINA_SAFETY_ON_NULL_RETURN_VAL(p_elements, 0);
+
+ element = e_connman_manager_get();
+ if (!element)
+ return 0;
+ return e_connman_element_objects_array_get_stringshared
+ (element, e_connman_prop_devices, count, p_elements);
+}
+
+/**
+ * Get array of connection elements.
+ *
+ * @param count return the number of elements in array.
+ * @param p_elements array with all elements, these are not referenced
+ * and in no particular order, just set if return is 1.
+ *
+ * @return 1 on success, 0 otherwise.
+ */
+bool
+e_connman_manager_connections_get(unsigned int *count, E_Connman_Element ***p_elements)
+{
+ E_Connman_Element *element;
+
+ EINA_SAFETY_ON_NULL_RETURN_VAL(count, 0);
+ EINA_SAFETY_ON_NULL_RETURN_VAL(p_elements, 0);
+
+ element = e_connman_manager_get();
+ if (!element)
+ return 0;
+ return e_connman_element_objects_array_get_stringshared
+ (element, e_connman_prop_connections, count, p_elements);
+}
--- /dev/null
+#include "e_connman_private.h"
+
+E_Connman_Element *
+e_connman_network_get(const char *path)
+{
+ E_Connman_Element *network;
+
+ EINA_SAFETY_ON_NULL_RETURN_VAL(path, NULL);
+
+ network = e_connman_element_get(path);
+ if (!network)
+ return NULL;
+
+ if (!e_connman_element_is_network(network))
+ {
+ WRN("path '%s' is not a network!\n", path);
+ return NULL;
+ }
+
+ return network;
+}
+
+/**
+ * Connect to network.
+ *
+ * Call method Connect() at the given network on server in order to
+ * connect to it.
+ *
+ * @param network_path to call method on server.
+ * @param cb function to call when server replies or some error happens.
+ * @param data data to give to cb when it is called.
+ *
+ * @return 1 on success, 0 otherwise.
+ */
+bool
+e_connman_network_connect(E_Connman_Element *network, E_DBus_Method_Return_Cb cb, const void *data)
+{
+ const char name[] = "Connect";
+
+ EINA_SAFETY_ON_NULL_RETURN_VAL(network, 0);
+ return e_connman_element_call_full
+ (network, name, NULL, &network->_pending.network_connect, cb, data);
+}
+
+/**
+ * Disconnect from network.
+ *
+ * Call method Disconnect() at the given network on server in order to
+ * disconnect from it.
+ *
+ * @param network_path to call method on server.
+ * @param cb function to call when server replies or some error happens.
+ * @param data data to give to cb when it is called.
+ *
+ * @return 1 on success, 0 otherwise.
+ */
+bool
+e_connman_network_disconnect(E_Connman_Element *network, E_DBus_Method_Return_Cb cb, const void *data)
+{
+ const char name[] = "Disconnect";
+
+ EINA_SAFETY_ON_NULL_RETURN_VAL(network, 0);
+ return e_connman_element_call_full
+ (network, name, NULL, &network->_pending.network_disconnect, cb, data);
+}
+
+/**
+ * Get property "Name" value.
+ *
+ * If this property isn't found then 0 is returned.
+ * If zero is returned, then this call failed and parameter-returned
+ * values shall be considered invalid.
+ *
+ * The pretty/long version of the network name. For
+ * example in case of WiFi this should be the UTF-8
+ * valid version of the SSID.
+ *
+ * @param network_path to get property.
+ * @param name where to store the property value, must be a pointer
+ * to string (const char **), it will not be allocated or
+ * copied and references will be valid until element changes,
+ * so copy it if you want to use it later.
+ *
+ * @return 1 on success, 0 otherwise.
+ */
+bool
+e_connman_network_name_get(const E_Connman_Element *network, const char **name)
+{
+ EINA_SAFETY_ON_NULL_RETURN_VAL(network, 0);
+ EINA_SAFETY_ON_NULL_RETURN_VAL(name, 0);
+ return e_connman_element_property_get_stringshared
+ (network, e_connman_prop_name, NULL, name);
+}
+
+/**
+ * Get property "Available" value.
+ *
+ * If this property isn't found then 0 is returned.
+ * If zero is returned, then this call failed and parameter-returned
+ * values shall be considered invalid.
+ *
+ * Indicates that this network is in range and
+ * ready to be used.
+ *
+ * The scanning process can change this property.
+ *
+ * @param network_path to get property.
+ * @param available where to store the property value, must be a pointer
+ * to boolean (bool **).
+ *
+ * @return 1 on success, 0 otherwise.
+ */
+bool
+e_connman_network_available_get(const E_Connman_Element *network, bool *available)
+{
+ EINA_SAFETY_ON_NULL_RETURN_VAL(network, 0);
+ EINA_SAFETY_ON_NULL_RETURN_VAL(available, 0);
+ return e_connman_element_property_get_stringshared
+ (network, e_connman_prop_available, NULL, available);
+}
+
+/**
+ * Get property "Connected" value.
+ *
+ * If this property isn't found then 0 is returned.
+ * If zero is returned, then this call failed and parameter-returned
+ * values shall be considered invalid.
+ *
+ * Indicates that this network is currently connected.
+ *
+ * @param network_path to get property.
+ * @param connected where to store the property value, must be a pointer
+ * to boolean (bool **).
+ *
+ * @return 1 on success, 0 otherwise.
+ */
+bool
+e_connman_network_connected_get(const E_Connman_Element *network, bool *connected)
+{
+ EINA_SAFETY_ON_NULL_RETURN_VAL(network, 0);
+ EINA_SAFETY_ON_NULL_RETURN_VAL(connected, 0);
+ return e_connman_element_property_get_stringshared
+ (network, e_connman_prop_connected, NULL, connected);
+}
+
+/**
+ * Get property "Remember" value.
+ *
+ * If this property isn't found then 0 is returned.
+ * If zero is returned, then this call failed and parameter-returned
+ * values shall be considered invalid.
+ *
+ * Indicates that this network will be remembered.
+ *
+ * For manually created networks this is set by
+ * default.
+ *
+ * @param network_path to get property.
+ * @param remember where to store the property value, must be a pointer
+ * to boolean (bool **).
+ *
+ * @return 1 on success, 0 otherwise.
+ * @see e_connman_network_remember_set()
+ */
+bool
+e_connman_network_remember_get(const E_Connman_Element *network, bool *remember)
+{
+ EINA_SAFETY_ON_NULL_RETURN_VAL(network, 0);
+ EINA_SAFETY_ON_NULL_RETURN_VAL(remember, 0);
+ return e_connman_element_property_get_stringshared
+ (network, e_connman_prop_remember, NULL, remember);
+}
+
+/**
+ * Call method SetProperty("Remember", remember) at the given element on server.
+ *
+ * This is a server call, not local, so it may fail and in that case
+ * no property is updated locally. If the value was set the event
+ * E_CONNMAN_EVENT_ELEMENT_UPDATED will be added to main loop.
+ *
+ * Indicates that this network will be remembered.
+ *
+ * For manually created networks this is set by
+ * default.
+ *
+ * @param network_path to set property.
+ * @param remember value to set.
+ * @param cb function to call when server replies or some error happens.
+ * @param data data to give to cb when it is called.
+ *
+ * @return 1 on success, 0 otherwise.
+ * @see e_connman_network_remember_get()
+ */
+bool
+e_connman_network_remember_set(E_Connman_Element *network, bool remember, E_DBus_Method_Return_Cb cb, const void *data)
+{
+ EINA_SAFETY_ON_NULL_RETURN_VAL(network, 0);
+ return e_connman_element_property_set_full
+ (network, e_connman_prop_remember, DBUS_TYPE_BOOLEAN, &remember, cb, data);
+}
+
+/**
+ * Get property "Strength" value.
+ *
+ * If this property isn't found then 0 is returned.
+ * If zero is returned, then this call failed and parameter-returned
+ * values shall be considered invalid.
+ *
+ * Indicates the signal strength of the network. This
+ * is a normalized value between 0 and 100.
+ *
+ * @param network_path to get property.
+ * @param strength where to store the property value, must be a pointer
+ * to byte (unsigned char*).
+ *
+ * @return 1 on success, 0 otherwise.
+ */
+bool
+e_connman_network_strength_get(const E_Connman_Element *network, unsigned char *strength)
+{
+ EINA_SAFETY_ON_NULL_RETURN_VAL(network, 0);
+ EINA_SAFETY_ON_NULL_RETURN_VAL(strength, 0);
+ return e_connman_element_property_get_stringshared
+ (network, e_connman_prop_strengh, NULL, strength);
+}
+
+/**
+ * Get the device element this network
+ * belongs to.
+ *
+ * @param network_path to get property.
+ * @param element where to store element, just changed if return is 1
+ *
+ * @return 1 on success, 0 otherwise
+ */
+bool
+e_connman_network_device_get(const E_Connman_Element *network, E_Connman_Element **element)
+{
+ char *device_path;
+
+ EINA_SAFETY_ON_NULL_RETURN_VAL(network, 0);
+ EINA_SAFETY_ON_NULL_RETURN_VAL(element, 0);
+
+ if (!e_connman_element_property_get_stringshared
+ (network, e_connman_prop_device, NULL, &device_path))
+ return 0;
+ *element = e_connman_element_get(device_path);
+ return 1;
+}
+
+/**
+ * Get property "WiFi.SSID" value.
+ *
+ * If this property isn't found then 0 is returned.
+ * If zero is returned, then this call failed and parameter-returned
+ * values shall be considered invalid.
+ *
+ * If the network type is WiFi, then this property is
+ * present and contains the binary SSID value.
+ *
+ * @param network_path to get property.
+ * @param count return the number of elements in array.
+ * @param wifi_ssid where to store the property value, must be a pointer
+ * to array of bytes (unsigned char **).
+ *
+ * @return 1 on success, 0 otherwise.
+ */
+bool
+e_connman_network_wifi_ssid_get(const E_Connman_Element *network, unsigned int *count, unsigned char **wifi_ssid)
+{
+ EINA_SAFETY_ON_NULL_RETURN_VAL(network, 0);
+ EINA_SAFETY_ON_NULL_RETURN_VAL(wifi_ssid, 0);
+ EINA_SAFETY_ON_NULL_RETURN_VAL(count, 0);
+ *wifi_ssid = e_connman_element_bytes_array_get_stringshared
+ (network, e_connman_prop_wifi_ssid, count);
+ if (!*wifi_ssid)
+ return 0;
+ return 1;
+}
+
+/**
+ * Get property "WiFi.Mode" value.
+ *
+ * If this property isn't found then 0 is returned.
+ * If zero is returned, then this call failed and parameter-returned
+ * values shall be considered invalid.
+ *
+ * If the network type is WiFi, then this property is
+ * present and contains the mode of the network. The
+ * possible values are "managed" or "adhoc".
+ *
+ * For scanned networks this value is read only, but in
+ * case the network was manually created it is also
+ * changeable.
+ *
+ * @param network_path to get property.
+ * @param wifi_mode where to store the property value, must be a pointer
+ * to string (const char **), it will not be allocated or
+ * copied and references will be valid until element changes,
+ * so copy it if you want to use it later.
+ *
+ * @return 1 on success, 0 otherwise.
+ * @see e_connman_network_wifi_mode_set()
+ */
+bool
+e_connman_network_wifi_mode_get(const E_Connman_Element *network, const char **wifi_mode)
+{
+ EINA_SAFETY_ON_NULL_RETURN_VAL(network, 0);
+ EINA_SAFETY_ON_NULL_RETURN_VAL(wifi_mode, 0);
+ return e_connman_element_property_get_stringshared
+ (network, e_connman_prop_wifi_mode, NULL, wifi_mode);
+}
+
+/**
+ * Call method SetProperty("WiFi.Mode", wifi_mode) at the given element on server.
+ *
+ * This is a server call, not local, so it may fail and in that case
+ * no property is updated locally. If the value was set the event
+ * E_CONNMAN_EVENT_ELEMENT_UPDATED will be added to main loop.
+ *
+ * If the network type is WiFi, then this property is
+ * present and contains the mode of the network. The
+ * possible values are "managed" or "adhoc".
+ *
+ * For scanned networks this value is read only, but in
+ * case the network was manually created it is also
+ * changeable.
+ *
+ * @param network_path to set property.
+ * @param wifi_mode value to set.
+ * @param cb function to call when server replies or some error happens.
+ * @param data data to give to cb when it is called.
+ *
+ * @return 1 on success, 0 otherwise.
+ * @see e_connman_network_wifi_mode_get()
+ */
+bool
+e_connman_network_wifi_mode_set(E_Connman_Element *network, const char *wifi_mode, E_DBus_Method_Return_Cb cb, const void *data)
+{
+ EINA_SAFETY_ON_NULL_RETURN_VAL(network, 0);
+ EINA_SAFETY_ON_NULL_RETURN_VAL(wifi_mode, 0);
+ return e_connman_element_property_set_full
+ (network, e_connman_prop_wifi_mode, DBUS_TYPE_STRING, wifi_mode, cb, data);
+}
+
+/**
+ * Get property "WiFi.Security" value.
+ *
+ * If this property isn't found then 0 is returned.
+ * If zero is returned, then this call failed and parameter-returned
+ * values shall be considered invalid.
+ *
+ * If the network type is WiFi, then this property is
+ * present and contains the security method or key
+ * management setting.
+ *
+ * For scanned networks this value is read only, but in
+ * case the network was manually created it is also
+ * changeable.
+ *
+ * Possible values are "none", "wep", "wpa" and "wpa2".
+ *
+ * @param network_path to get property.
+ * @param wifi_security where to store the property value, must be a pointer
+ * to string (const char **), it will not be allocated or
+ * copied and references will be valid until element changes,
+ * so copy it if you want to use it later.
+ *
+ * @return 1 on success, 0 otherwise.
+ * @see e_connman_network_wifi_security_set()
+ */
+bool
+e_connman_network_wifi_security_get(const E_Connman_Element *network, const char **wifi_security)
+{
+ EINA_SAFETY_ON_NULL_RETURN_VAL(network, 0);
+ EINA_SAFETY_ON_NULL_RETURN_VAL(wifi_security, 0);
+ return e_connman_element_property_get_stringshared
+ (network, e_connman_prop_wifi_security, NULL, wifi_security);
+}
+
+/**
+ * Call method SetProperty("WiFi.Security", wifi_security) at the given element on server.
+ *
+ * This is a server call, not local, so it may fail and in that case
+ * no property is updated locally. If the value was set the event
+ * E_CONNMAN_EVENT_ELEMENT_UPDATED will be added to main loop.
+ *
+ * If the network type is WiFi, then this property is
+ * present and contains the security method or key
+ * management setting.
+ *
+ * For scanned networks this value is read only, but in
+ * case the network was manually created it is also
+ * changeable.
+ *
+ * Possible values are "none", "wep", "wpa" and "wpa2".
+ *
+ * @param network_path to set property.
+ * @param wifi_security value to set.
+ * @param cb function to call when server replies or some error happens.
+ * @param data data to give to cb when it is called.
+ *
+ * @return 1 on success, 0 otherwise.
+ * @see e_connman_network_wifi_security_get()
+ */
+bool
+e_connman_network_wifi_security_set(E_Connman_Element *network, const char *wifi_security, E_DBus_Method_Return_Cb cb, const void *data)
+{
+ EINA_SAFETY_ON_NULL_RETURN_VAL(network, 0);
+ EINA_SAFETY_ON_NULL_RETURN_VAL(wifi_security, 0);
+ return e_connman_element_property_set_full
+ (network, e_connman_prop_wifi_security, DBUS_TYPE_STRING,
+ wifi_security, cb, data);
+}
+
+/**
+ * Get property "WiFi.Passphrase" value.
+ *
+ * If this property isn't found then 0 is returned.
+ * If zero is returned, then this call failed and parameter-returned
+ * values shall be considered invalid.
+ *
+ * If the network type is WiFi and a passhrase is
+ * requires, then this property is present and contains
+ * the passphrase in clear text.
+ *
+ * For systems using PolicyKit, the access to this value
+ * will be protected by the security policy.
+ *
+ * @param network_path to get property.
+ * @param wifi_passphrase where to store the property value, must be a pointer
+ * to string (const char **), it will not be allocated or
+ * copied and references will be valid until element changes,
+ * so copy it if you want to use it later.
+ *
+ * @return 1 on success, 0 otherwise.
+ * @see e_connman_network_wifi_passphrase_set()
+ */
+bool
+e_connman_network_wifi_passphrase_get(const E_Connman_Element *network, const char **wifi_passphrase)
+{
+ EINA_SAFETY_ON_NULL_RETURN_VAL(network, 0);
+ EINA_SAFETY_ON_NULL_RETURN_VAL(wifi_passphrase, 0);
+ return e_connman_element_property_get_stringshared
+ (network, e_connman_prop_wifi_passphrase, NULL, wifi_passphrase);
+}
+
+/**
+ * Call method SetProperty("WiFi.Passphrase", wifi_passphrase) at the given element on server.
+ *
+ * This is a server call, not local, so it may fail and in that case
+ * no property is updated locally. If the value was set the event
+ * E_CONNMAN_EVENT_ELEMENT_UPDATED will be added to main loop.
+ *
+ * If the network type is WiFi and a passhrase is
+ * requires, then this property is present and contains
+ * the passphrase in clear text.
+ *
+ * For systems using PolicyKit, the access to this value
+ * will be protected by the security policy.
+ *
+ * @param network_path to set property.
+ * @param wifi_passphrase value to set.
+ * @param cb function to call when server replies or some error happens.
+ * @param data data to give to cb when it is called.
+ *
+ * @return 1 on success, 0 otherwise.
+ * @see e_connman_network_wifi_passphrase_get()
+ */
+bool
+e_connman_network_wifi_passphrase_set(E_Connman_Element *network, const char *wifi_passphrase, E_DBus_Method_Return_Cb cb, const void *data)
+{
+ EINA_SAFETY_ON_NULL_RETURN_VAL(network, 0);
+ return e_connman_element_property_set_full
+ (network, e_connman_prop_wifi_passphrase, DBUS_TYPE_STRING,
+ wifi_passphrase, cb, data);
+}
--- /dev/null
+#include <Eina.h>
+#include <eina_safety_checks.h>
+
+#include "E_Connman.h"
+#include <stdio.h>
+
+static const char manager_path[] = "/";
+
+extern const char *e_connman_iface_manager;
+extern const char *e_connman_iface_network;
+extern const char *e_connman_iface_profile;
+extern const char *e_connman_iface_service;
+extern const char *e_connman_iface_device;
+extern const char *e_connman_iface_connection;
+
+extern const char *e_connman_prop_available;
+extern const char *e_connman_prop_connected;
+extern const char *e_connman_prop_connections;
+extern const char *e_connman_prop_default;
+extern const char *e_connman_prop_device;
+extern const char *e_connman_prop_devices;
+extern const char *e_connman_prop_interface;
+extern const char *e_connman_prop_ipv4_address;
+extern const char *e_connman_prop_ipv4_method;
+extern const char *e_connman_prop_name;
+extern const char *e_connman_prop_network;
+extern const char *e_connman_prop_networks;
+extern const char *e_connman_prop_offline_mode;
+extern const char *e_connman_prop_policy;
+extern const char *e_connman_prop_powered;
+extern const char *e_connman_prop_priority;
+extern const char *e_connman_prop_profiles;
+extern const char *e_connman_prop_remember;
+extern const char *e_connman_prop_scan_interval;
+extern const char *e_connman_prop_scanning;
+extern const char *e_connman_prop_state;
+extern const char *e_connman_prop_strengh;
+extern const char *e_connman_prop_type;
+extern const char *e_connman_prop_wifi_mode;
+extern const char *e_connman_prop_wifi_passphrase;
+extern const char *e_connman_prop_wifi_security;
+extern const char *e_connman_prop_wifi_ssid;
+
+
+#define DBG(...) EINA_ERROR_PDBG(__VA_ARGS__)
+#define INF(...) EINA_ERROR_PINFO(__VA_ARGS__)
+#define WRN(...) EINA_ERROR_PWARN(__VA_ARGS__)
+#define ERR(...) EINA_ERROR_PERR(__VA_ARGS__)
+
+static inline bool
+__dbus_callback_check_and_init(const char *file, int line, const char *function, DBusMessage *msg, DBusMessageIter *itr, DBusError *err)
+{
+ if (!msg)
+ {
+ if (err)
+ eina_error_print(EINA_ERROR_LEVEL_ERR, file, function, line,
+ "an error was reported by server: "
+ "name=\"%s\", message=\"%s\"\n",
+ err->name, err->message);
+ else
+ eina_error_print(EINA_ERROR_LEVEL_ERR, file, function, line,
+ "callback without message arguments!\n");
+
+ return 0;
+ }
+
+ if (!dbus_message_iter_init(msg, itr))
+ {
+ eina_error_print(EINA_ERROR_LEVEL_ERR, file, function, line,
+ "could not init iterator.\n");
+ return 0;
+ }
+
+ return 1;
+}
+
+#define _dbus_callback_check_and_init(msg, itr, err) \
+ __dbus_callback_check_and_init(__FILE__, __LINE__, __FUNCTION__, \
+ msg, itr, err)
+
+static inline bool
+__dbus_iter_type_check(const char *file, int line, const char *function, int type, int expected, const char *expected_name)
+{
+ if (type == expected)
+ return 1;
+
+ eina_error_print(EINA_ERROR_LEVEL_ERR, file, function, line,
+ "expected type %s (%c) but got %c instead!\n",
+ expected_name, expected, type);
+
+ return 0;
+}
+#define _dbus_iter_type_check(t, e) __dbus_iter_type_check(__FILE__, __LINE__, __FUNCTION__, t, e, #e)
+
+extern E_DBus_Connection *e_connman_conn;
+
+const char *e_connman_system_bus_name_get(void);
+
+void e_connman_manager_clear_elements(void);
+
+void e_connman_elements_init(void);
+void e_connman_elements_shutdown(void);
+
+E_Connman_Element *e_connman_element_register(const char *path, const char *interface);
+void e_connman_element_unregister(E_Connman_Element *element);
+
+bool e_connman_element_objects_array_get_stringshared(const E_Connman_Element *element, const char *property, unsigned int *count, E_Connman_Element ***elements);
+unsigned char *e_connman_element_bytes_array_get_stringshared(const E_Connman_Element *element, const char *property, unsigned int *count);
+
+bool e_connman_element_call_with_path(E_Connman_Element *element, const char *method_name, const char *string, E_DBus_Method_Return_Cb cb, Eina_Inlist **pending, E_DBus_Method_Return_Cb user_cb, const void *user_data);
+
+bool e_connman_element_message_send(E_Connman_Element *element, const char *method_name, E_DBus_Method_Return_Cb cb, DBusMessage *msg, Eina_Inlist **pending, E_DBus_Method_Return_Cb user_cb, const void *user_data);
+
+bool e_connman_element_call_full(E_Connman_Element *element, const char *method_name, E_DBus_Method_Return_Cb cb, Eina_Inlist **pending, E_DBus_Method_Return_Cb user_cb, const void *user_data);
--- /dev/null
+#include "e_connman_private.h"
+
+E_Connman_Element *
+e_connman_profile_get(const char *path)
+{
+ E_Connman_Element *profile;
+
+ EINA_SAFETY_ON_NULL_RETURN_VAL(path, NULL);
+
+ profile = e_connman_element_get(path);
+ if (!profile)
+ return NULL;
+
+ if (!e_connman_element_is_profile(profile))
+ {
+ WRN("path '%s' is not a profile!\n", path);
+ return NULL;
+ }
+
+ return profile;
+}
+
+/**
+ * Get property "Name" value.
+ *
+ * If this property isn't found then 0 is returned.
+ * If zero is returned, then this call failed and parameter-returned
+ * values shall be considered invalid.
+ *
+ * The profile name.
+ *
+ * @param profile_path to get property.
+ * @param name where to store the property value, must be a pointer
+ * to string (const char **), it will not be allocated or
+ * copied and references will be valid until element changes,
+ * so copy it if you want to use it later.
+ *
+ * @return 1 on success, 0 otherwise.
+ */
+bool
+e_connman_profile_name_get(const E_Connman_Element *profile, const char **name)
+{
+ EINA_SAFETY_ON_NULL_RETURN_VAL(profile, 0);
+ EINA_SAFETY_ON_NULL_RETURN_VAL(name, 0);
+ return e_connman_element_property_get_stringshared
+ (profile, e_connman_prop_name, NULL, name);
+}