diff options
author | Marcel Holtmann <marcel@holtmann.org> | 2010-01-25 07:14:11 +0100 |
---|---|---|
committer | Marcel Holtmann <marcel@holtmann.org> | 2010-01-25 07:14:11 +0100 |
commit | 32d267c1a6083f3f5183e5f3f15161b097f37419 (patch) | |
tree | 4de626ebde91e5104e02129d342a33c61206f47c | |
parent | b5795c2b12e34ab29ad283b2ece3a507b17e3cb9 (diff) | |
download | connman-32d267c1a6083f3f5183e5f3f15161b097f37419.tar.gz connman-32d267c1a6083f3f5183e5f3f15161b097f37419.tar.bz2 connman-32d267c1a6083f3f5183e5f3f15161b097f37419.zip |
Add support for technology interface
-rw-r--r-- | Makefile.am | 2 | ||||
-rw-r--r-- | doc/manager-api.txt | 4 | ||||
-rw-r--r-- | doc/technology-api.txt | 34 | ||||
-rw-r--r-- | include/dbus.h | 2 | ||||
-rw-r--r-- | src/connman.h | 6 | ||||
-rw-r--r-- | src/device.c | 15 | ||||
-rw-r--r-- | src/manager.c | 5 | ||||
-rw-r--r-- | src/technology.c | 265 | ||||
-rwxr-xr-x | test/list-devices | 34 | ||||
-rwxr-xr-x | test/monitor-manager | 2 | ||||
-rwxr-xr-x | test/monitor-services | 2 | ||||
-rwxr-xr-x | test/test-manager | 14 |
12 files changed, 349 insertions, 36 deletions
diff --git a/Makefile.am b/Makefile.am index ce348ed6..15b41a6f 100644 --- a/Makefile.am +++ b/Makefile.am @@ -153,7 +153,7 @@ EXTRA_DIST += doc/overview-api.txt doc/behavior-api.txt \ doc/ipconfig-api.txt doc/plugin-api.txt \ doc/manager-api.txt doc/agent-api.txt \ doc/profile-api.txt doc/service-api.txt \ - doc/counter-api.txt \ + doc/technology-api.txt doc/counter-api.txt \ doc/device-lowlevel-api.txt \ doc/network-lowlevel-api.txt \ doc/advanced-configuration.txt diff --git a/doc/manager-api.txt b/doc/manager-api.txt index 1ba0480c..c8989353 100644 --- a/doc/manager-api.txt +++ b/doc/manager-api.txt @@ -187,9 +187,9 @@ Properties string State [readonly] List of profile object paths. - array{object} Devices [readonly] + array{object} Technologies [readonly] - List of device object paths. + List of technology object paths. array{object} Services [readonly] diff --git a/doc/technology-api.txt b/doc/technology-api.txt new file mode 100644 index 00000000..9b10c583 --- /dev/null +++ b/doc/technology-api.txt @@ -0,0 +1,34 @@ +Technology hierarchy +==================== + +Service org.moblin.connman +Interface org.moblin.connman.Technology +Object path [variable prefix]/{technology0,technology1,...} + +Methods dict GetProperties() + + Returns properties for the technology object. See + the properties section for available properties. + + Possible Errors: [service].Error.InvalidArguments + +Signals PropertyChanged(string name, variant value) + + This signal indicates a changed value of the given + property. + +Properties string Name [readonly] + + Name of this technology. + + string Type [readonly] + + The technology type (for example "ethernet" etc.) + + This information should only be used to determine + advanced properties or showing the correct icon + to the user. + + array{object} Devices [readonly] + + List of device objects. diff --git a/include/dbus.h b/include/dbus.h index 36629dfb..2ff41b2a 100644 --- a/include/dbus.h +++ b/include/dbus.h @@ -29,6 +29,7 @@ extern "C" { #endif #define CONNMAN_SERVICE "org.moblin.connman" +#define CONNMAN_PATH "/org/moblin/connman" #define CONNMAN_DEBUG_INTERFACE CONNMAN_SERVICE ".Debug" #define CONNMAN_ERROR_INTERFACE CONNMAN_SERVICE ".Error" @@ -44,6 +45,7 @@ extern "C" { #define CONNMAN_DEVICE_INTERFACE CONNMAN_SERVICE ".Device" #define CONNMAN_NETWORK_INTERFACE CONNMAN_SERVICE ".Network" #define CONNMAN_PROVIDER_INTERFACE CONNMAN_SERVICE ".Provider" +#define CONNMAN_TECHNOLOGY_INTERFACE CONNMAN_SERVICE ".Technology" typedef void (* connman_dbus_append_cb_t) (DBusMessageIter *iter, void *user_data); diff --git a/src/connman.h b/src/connman.h index a7040270..d399634d 100644 --- a/src/connman.h +++ b/src/connman.h @@ -269,6 +269,11 @@ connman_bool_t __connman_udev_get_blocked(int phyindex); #include <connman/device.h> +void __connman_technology_list(DBusMessageIter *iter, void *user_data); + +int __connman_technology_add_device(struct connman_device *device); +int __connman_technology_remove_device(struct connman_device *device); + int __connman_device_init(void); void __connman_device_cleanup(void); @@ -282,7 +287,6 @@ void __connman_device_set_phyindex(struct connman_device *device, int __connman_device_set_blocked(struct connman_device *device, connman_bool_t blocked); - void __connman_device_increase_connections(struct connman_device *device); void __connman_device_decrease_connections(struct connman_device *device); diff --git a/src/device.c b/src/device.c index 875b1972..c78e4219 100644 --- a/src/device.c +++ b/src/device.c @@ -478,13 +478,6 @@ static GDBusSignalTable device_signals[] = { { }, }; -static void emit_devices_signal(void) -{ - connman_dbus_property_changed_array(CONNMAN_MANAGER_PATH, - CONNMAN_MANAGER_INTERFACE, "Devices", - DBUS_TYPE_OBJECT_PATH, __connman_device_list, NULL); -} - static int register_interface(struct connman_element *element) { struct connman_device *device = element->device; @@ -501,8 +494,6 @@ static int register_interface(struct connman_element *element) device->registered = TRUE; - emit_devices_signal(); - return 0; } @@ -514,8 +505,6 @@ static void unregister_interface(struct connman_element *element) device->registered = FALSE; - emit_devices_signal(); - g_dbus_unregister_interface(connection, element->path, CONNMAN_DEVICE_INTERFACE); } @@ -535,6 +524,8 @@ static int setup_device(struct connman_device *device) return err; } + __connman_technology_add_device(device); + type = __connman_device_get_service_type(device); __connman_notifier_register(type); @@ -596,6 +587,8 @@ static void remove_device(struct connman_device *device) type = __connman_device_get_service_type(device); __connman_notifier_unregister(type); + __connman_technology_remove_device(device); + unregister_interface(&device->element); if (device->driver->remove) diff --git a/src/manager.c b/src/manager.c index 7b2f9963..141e9593 100644 --- a/src/manager.c +++ b/src/manager.c @@ -60,9 +60,8 @@ static DBusMessage *get_properties(DBusConnection *conn, DBUS_TYPE_OBJECT_PATH, __connman_service_list, NULL); connman_dbus_dict_append_array(&dict, "Providers", DBUS_TYPE_OBJECT_PATH, __connman_provider_list, NULL); - - connman_dbus_dict_append_array(&dict, "Devices", - DBUS_TYPE_OBJECT_PATH, __connman_device_list, NULL); + connman_dbus_dict_append_array(&dict, "Technologies", + DBUS_TYPE_OBJECT_PATH, __connman_technology_list, NULL); str = __connman_notifier_get_state(); connman_dbus_dict_append_basic(&dict, "State", diff --git a/src/technology.c b/src/technology.c index 6c460743..33fbc75b 100644 --- a/src/technology.c +++ b/src/technology.c @@ -23,16 +23,281 @@ #include <config.h> #endif +#include <gdbus.h> + #include "connman.h" +static DBusConnection *connection; + +static GHashTable *device_table; +static GSList *technology_list = NULL; + +struct connman_technology { + gint refcount; + enum connman_service_type type; + char *path; + GSList *device_list; +}; + +void __connman_technology_list(DBusMessageIter *iter, void *user_data) +{ + GSList *list; + + for (list = technology_list; list; list = list->next) { + struct connman_technology *technology = list->data; + + if (technology->path == NULL) + continue; + + dbus_message_iter_append_basic(iter, DBUS_TYPE_OBJECT_PATH, + &technology->path); + } +} + +static void technologies_changed(void) +{ + connman_dbus_property_changed_array(CONNMAN_MANAGER_PATH, + CONNMAN_MANAGER_INTERFACE, "Technologies", + DBUS_TYPE_OBJECT_PATH, __connman_technology_list, NULL); +} + +static void device_list(DBusMessageIter *iter, void *user_data) +{ + struct connman_technology *technology = user_data; + GSList *list; + + for (list = technology->device_list; list; list = list->next) { + struct connman_device *device = list->data; + const char *path; + + path = connman_device_get_path(device); + if (path == NULL) + continue; + + dbus_message_iter_append_basic(iter, DBUS_TYPE_OBJECT_PATH, + &path); + } +} + +static void devices_changed(struct connman_technology *technology) +{ + connman_dbus_property_changed_array(technology->path, + CONNMAN_TECHNOLOGY_INTERFACE, "Devices", + DBUS_TYPE_OBJECT_PATH, device_list, technology); +} + +static const char *get_name(enum connman_service_type type) +{ + switch (type) { + case CONNMAN_SERVICE_TYPE_UNKNOWN: + case CONNMAN_SERVICE_TYPE_SYSTEM: + case CONNMAN_SERVICE_TYPE_GPS: + case CONNMAN_SERVICE_TYPE_VPN: + break; + case CONNMAN_SERVICE_TYPE_ETHERNET: + return "Wired"; + case CONNMAN_SERVICE_TYPE_WIFI: + return "WiFi"; + case CONNMAN_SERVICE_TYPE_WIMAX: + return "WiMAX"; + case CONNMAN_SERVICE_TYPE_BLUETOOTH: + return "Bluetooth"; + case CONNMAN_SERVICE_TYPE_CELLULAR: + return "3G"; + } + + return NULL; +} + +static DBusMessage *get_properties(DBusConnection *conn, + DBusMessage *message, void *user_data) +{ + struct connman_technology *technology = user_data; + DBusMessage *reply; + DBusMessageIter array, dict; + const char *str; + + reply = dbus_message_new_method_return(message); + if (reply == NULL) + return NULL; + + dbus_message_iter_init_append(reply, &array); + + connman_dbus_dict_open(&array, &dict); + + str = get_name(technology->type); + if (str != NULL) + connman_dbus_dict_append_basic(&dict, "Name", + DBUS_TYPE_STRING, &str); + + str = __connman_service_type2string(technology->type); + if (str != NULL) + connman_dbus_dict_append_basic(&dict, "Type", + DBUS_TYPE_STRING, &str); + + connman_dbus_dict_append_array(&dict, "Devices", + DBUS_TYPE_OBJECT_PATH, device_list, technology); + + connman_dbus_dict_close(&array, &dict); + + return reply; +} + +static GDBusMethodTable technology_methods[] = { + { "GetProperties", "", "a{sv}", get_properties }, + { }, +}; + +static GDBusSignalTable technology_signals[] = { + { "PropertyChanged", "sv" }, + { }, +}; + +static struct connman_technology *technology_find(enum connman_service_type type) +{ + GSList *list; + + DBG("type %d", type); + + for (list = technology_list; list; list = list->next) { + struct connman_technology *technology = list->data; + + if (technology->type == type) + return technology; + } + + return NULL; +} + +static struct connman_technology *technology_get(enum connman_service_type type) +{ + static unsigned int counter = 0; + struct connman_technology *technology; + + DBG("type %d", type); + + technology = technology_find(type); + if (technology != NULL) { + g_atomic_int_inc(&technology->refcount); + goto done; + } + + technology = g_try_new0(struct connman_technology, 1); + if (technology == NULL) + return NULL; + + technology->refcount = 1; + + technology->type = type; + technology->path = g_strdup_printf("%s/technology%d", + CONNMAN_PATH, counter++); + + if (g_dbus_register_interface(connection, technology->path, + CONNMAN_TECHNOLOGY_INTERFACE, + technology_methods, technology_signals, + NULL, technology, NULL) == FALSE) { + connman_error("Failed to register %s", technology->path); + g_free(technology); + return NULL; + } + + technology_list = g_slist_append(technology_list, technology); + + technologies_changed(); + +done: + DBG("technology %p", technology); + + return technology; +} + +static void technology_put(struct connman_technology *technology) +{ + DBG("technology %p", technology); + + if (g_atomic_int_dec_and_test(&technology->refcount) == FALSE) + return; + + technology_list = g_slist_remove(technology_list, technology); + + technologies_changed(); + + g_dbus_unregister_interface(connection, technology->path, + CONNMAN_TECHNOLOGY_INTERFACE); + + g_free(technology->path); + g_free(technology); +} + +static void unregister_device(gpointer data) +{ + struct connman_technology *technology = data; + + DBG("technology %p", technology); + + technology_put(technology); +} + +int __connman_technology_add_device(struct connman_device *device) +{ + struct connman_technology *technology; + enum connman_service_type type; + + DBG("device %p", device); + + type = __connman_device_get_service_type(device); + + technology = technology_get(type); + if (technology == NULL) + return -ENXIO; + + g_hash_table_insert(device_table, device, technology); + + technology->device_list = g_slist_append(technology->device_list, + device); + + devices_changed(technology); + + return 0; +} + +int __connman_technology_remove_device(struct connman_device *device) +{ + struct connman_technology *technology; + + DBG("device %p", device); + + technology = g_hash_table_lookup(device_table, device); + if (technology == NULL) + return -ENXIO; + + technology->device_list = g_slist_remove(technology->device_list, + device); + + devices_changed(technology); + + g_hash_table_remove(device_table, device); + + return 0; +} + int __connman_technology_init(void) { DBG(""); + connection = connman_dbus_get_connection(); + + device_table = g_hash_table_new_full(g_direct_hash, g_direct_equal, + NULL, unregister_device); + return 0; } void __connman_technology_cleanup(void) { DBG(""); + + g_hash_table_destroy(device_table); + + dbus_connection_unref(connection); } diff --git a/test/list-devices b/test/list-devices index 61d8bbcf..78c319b3 100755 --- a/test/list-devices +++ b/test/list-devices @@ -9,21 +9,27 @@ manager = dbus.Interface(bus.get_object("org.moblin.connman", "/"), properties = manager.GetProperties() -for path in properties["Devices"]: - device = dbus.Interface(bus.get_object("org.moblin.connman", path), - "org.moblin.connman.Device") +for path in properties["Technologies"]: + technology = dbus.Interface(bus.get_object("org.moblin.connman", path), + "org.moblin.connman.Technology") - properties = device.GetProperties() + properties = technology.GetProperties() - print "[ %s ]" % (path) + for path in properties["Devices"]: + device = dbus.Interface(bus.get_object("org.moblin.connman", path), + "org.moblin.connman.Device") - for key in properties.keys(): - if key in ["Networks"]: - val = "" - for i in properties[key]: - val += i + " " - else: - val = str(properties[key]) - print " %s = %s" % (key, val) + properties = device.GetProperties() - print + print "[ %s ]" % (path) + + for key in properties.keys(): + if key in ["Networks"]: + val = "" + for i in properties[key]: + val += i + " " + else: + val = str(properties[key]) + print " %s = %s" % (key, val) + + print diff --git a/test/monitor-manager b/test/monitor-manager index a6192421..82ca805b 100755 --- a/test/monitor-manager +++ b/test/monitor-manager @@ -6,7 +6,7 @@ import dbus import dbus.mainloop.glib def property_changed(name, value): - if name in ["Profiles", "Services", "Providers", + if name in ["Profiles", "Services", "Providers", "Technologies", "Devices", "Networks"]: val = "[" for i in value: diff --git a/test/monitor-services b/test/monitor-services index c435a34a..7d654471 100755 --- a/test/monitor-services +++ b/test/monitor-services @@ -10,7 +10,7 @@ def property_changed(name, value, path, interface): ipath = path[path.rfind("/") + 1:] if iface not in ["Service"]: return - if name in ["Profiles", "Services", "Providers", + if name in ["Profiles", "Services", "Providers", "Technologies", "Devices", "Networks"]: val = "[" for i in value: diff --git a/test/test-manager b/test/test-manager index a41d6570..6f9c2004 100755 --- a/test/test-manager +++ b/test/test-manager @@ -18,6 +18,8 @@ def print_properties(key, value): interface = "org.moblin.connman.Service" elif key == "Providers": interface = "org.moblin.connman.Provider" + elif key == "Technologies": + interface = "org.moblin.connman.Technology" else: return @@ -30,7 +32,8 @@ def print_properties(key, value): properties = obj.GetProperties() for key in properties.keys(): - if key in ["Networks", "Services", "Providers"]: + if key in ["Devices", "Networks", "Services", + "Providers", "Technologies"]: continue if key in ["Powered", "Scanning", "Connected", @@ -46,6 +49,12 @@ def print_properties(key, value): print " %s = %s" % (key, val) + if "Devices" in properties.keys(): + list = "" + for path in properties["Devices"]: + val = str(path) + list = list + val[val.rfind("/") + 1:] + " " + print " Devices = [ %s]" % (list) if "Networks" in properties.keys(): list = "" for path in properties["Networks"]: @@ -67,7 +76,8 @@ def print_properties(key, value): for key in properties.keys(): - if key in ["Profiles", "Devices", "Services", "Providers"]: + if key in ["Profiles", "Devices", "Services", "Providers", + "Technologies"]: print_properties(key, properties[key]) elif key in ["AvailableTechnologies", "EnabledTechnologies", "ConnectedTechnologies", |